flutter 在前台和后台收到firebase通知时显示抖动本地通知

uubf1zoe  于 2023-03-31  发布在  Flutter
关注(0)|答案(2)|浏览(261)

我试图在后台,前台和应用程序的终止状态下接收Firebase通知时显示Flutter本地通知。我试图使用工作管理器包解决此问题,它在Android中工作得很好。它在前台,后台和终止状态下也可以工作但是它在iOS设备中不工作。如果我试图执行任务,这是没有注册的信息plist和appDelegate它给我一个错误,但注册后,它没有做任何事情(没有错误,也没有执行我的代码).我想我的任务是注册,但iOS没有执行它在某种原因.如果有人做了类似的事情,请提供一些例子,或者也许我做错了什么一些想法?
尝试使用工作管理器和 Flutter 本地通知解决问题

xcitsw88

xcitsw881#

我为这个问题挣扎了好几个星期,直到我设法让通知出现在我的ios应用程序上,而不管它的状态如何。
首先,您必须在Xcode中勾选“后台获取”和“后台处理”模式。这些可以在签名和功能下找到。

接下来,您必须在AppDelegate. swift中注册任务并给予应用通知功能。

override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    GeneratedPluginRegistrant.register(with: self)
    UNUserNotificationCenter.current().delegate = self

    WorkmanagerPlugin.setPluginRegistrantCallback { registry in
      // Registry, in this case is the FlutterEngine that is created in Workmanager's
      // performFetchWithCompletionHandler or BGAppRefreshTask.
      // This will make other plugins available during a background operation.
      GeneratedPluginRegistrant.register(with: registry)
    }

    // you will need to duplicate the line below for each identifier
    WorkmanagerPlugin.registerTask(withIdentifier: "your.task.identifier")

    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }

  override func userNotificationCenter(
      _ center: UNUserNotificationCenter,
      willPresent notification: UNNotification,
      withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        completionHandler(.alert) // shows banner even if app is in foreground
    }

}

您还需要在info.plist中注册您的任务,如下所示:

<key>BGTaskSchedulerPermittedIdentifiers</key>
    <array>
        <string>your.task.identifier/string>
    </array>
    <key>UIBackgroundModes</key>
    <array>
        <string>fetch</string>
        <string>processing</string>
    </array>

registerPeriodicTask不适用于ios,所以应该使用flutter_local_notifications的periodicallyShow函数。
作为参考,我提供了我的代码片段,它显示了我如何使用workmanager和flutter_local_notifications;

void registerWorkmanagerTask() async {
  try {
    await Workmanager().registerOneOffTask(
      AppConstants.notifyReviewTask,
      AppConstants.notifyReviewTask,
      initialDelay: Duration(hours: 4),
      existingWorkPolicy: ExistingWorkPolicy.replace,
      backoffPolicy: BackoffPolicy.linear,
    );
  } catch (e) {
    print("exception caught $e");
  }
}

@pragma('vm:entry-point')
void callbackDispatcher() {
  Workmanager().executeTask((taskName, _) async {
    try {
      await NotificaitonService().setup();
      if (taskName == AppConstants.notifyReviewTask)
        await NotificaitonService().showNotification(
          body: 'items are ready to be reviewed',
          notificationId: AppConstants.recallNotificationId,
          channel: AppConstants.recallChannel,
          title: 'Time to review',
        );
      return Future.value(true);
    } catch (e) {
      print("exception caught $e");
    }
  });
}

请记住,ios设备可以出于多种原因(例如电池电量不足)决定推迟运行后台工作管理器任务,而且,使用ios模拟器不会显示通知。

8xiog9wr

8xiog9wr2#

你可以通过使用flutter_local_notification做到这一点,如果你是开放的.它是更简单和紧凑.
预先申请:
1.安装以下软件包:

firebase_core
firebase_messaging 
flutter_local_notifications

1.后台和终止状态的通知由flutter应用程序处理,默认通知服务
1.应该创建前台通知,这里我们使用flutter_local_notification创建监听fcm流。

完整代码:

import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:hello/notification_helper.dart';

Future<void> _firebaseMessagingBackgroundHandler(message) async {
  await Firebase.initializeApp();
  print('Handling a background message ${message.messageId}');
}

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  final fcmToken = await FirebaseMessaging.instance.getToken();
  debugPrint(fcmToken);
  FirebaseMessaging messaging = FirebaseMessaging.instance;

  NotificationSettings settings = await messaging.requestPermission(
    alert: true,
    announcement: false,
    badge: true,
    carPlay: false,
    criticalAlert: false,
    provisional: false,
    sound: true,
  );

  if (settings.authorizationStatus == AuthorizationStatus.authorized) {
    print('User granted permission');
  } else if (settings.authorizationStatus == AuthorizationStatus.provisional) {
    print('User granted provisional permission');
  } else {
    print('User declined or has not accepted permission');
  }
  FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  void initState() {
    LocalNotification.initialize();
    FirebaseMessaging.onMessage.listen((RemoteMessage message) {
      LocalNotification.showNotification(message);
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(
      child: Text("Hello"),
    ));
  }
}

notification_helper.dart//类显式处理前台通知

import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';

class LocalNotification {
  static final FlutterLocalNotificationsPlugin _notiPlugin =
      FlutterLocalNotificationsPlugin();

  static void initialize() {
    final InitializationSettings initialSettings = InitializationSettings(
      android: AndroidInitializationSettings(
        '@mipmap/ic_launcher',
      ),
    );
    _notiPlugin.initialize(initialSettings,
        onDidReceiveNotificationResponse: (NotificationResponse details) {
      print('onDidReceiveNotificationResponse Function');
      print(details.payload);
      print(details.payload != null);
    });
  }

  static void showNotification(RemoteMessage message) {
    final NotificationDetails notiDetails = NotificationDetails(
      android: AndroidNotificationDetails(
        'com.example.push_notification',
        'push_notification',
        importance: Importance.max,
        priority: Priority.high,
      ),
    );
    _notiPlugin.show(
      DateTime.now().microsecond,
      message.notification!.title,
      message.notification!.body,
      notiDetails,
      payload: message.data.toString(),
    );
  }
}

相关问题