如何在Flutter中使用最新版本配置Firebase消息传递?

51
我曾经使用以下代码行来配置Flutter通知的Firebase消息配置,但是现在在集成最新版本的Firebase消息后,它给我报错了。
代码行:
 messaging.configure(onMessage: (Map<String, dynamic> message){}

DART分析错误

error: The method 'configure' isn't defined for the type 'FirebaseMessaging'. 

你能否请发布一下你用于配置 Firebase Messaging 的完整代码? - basudev nayak
1
你正在使用哪个版本的 Firebase 消息传递? - humblePilgrim
3
最新的 firebase_messaging ^8.0.0-dev.10 可以从 FlutterFire 的链接 https://firebase.flutter.dev/docs/migration/ 获取。 - user14707939
8个回答

118

FirebaseMessaging.configure() 已被 Firebase 团队删除:根据 https://firebase.flutter.dev/docs/migration/#messaging

原因:如果多次调用 configure()(无论是为了注册不同的处理程序还是删除处理程序),先前的实现会导致意外副作用。此更改允许开发人员更明确地注册处理程序并删除它们,而不通过 Streams 影响其他人。

使用 FirebaseMessaging.onMessage 方法来获取消息。

FirebaseMessaging.onMessage.listen((RemoteMessage message) {
      RemoteNotification notification = message.notification;
      AndroidNotification android = message.notification?.android;
    });

使用FirebaseMessaging.onMessageOpenedApp作为onLaunchonResume处理程序的替代方法。
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
      print('A new onMessageOpenedApp event was published!');
      Navigator.pushNamed(context, '/message',
          arguments: MessageArguments(message, true));
    });

28
我花了2个小时查找清晰的解释,但是在文档和变更日志中没有找到,最终在这里找到了。 - Mehmet Filiz
谢谢。这个答案应该被标记为已选答案。 - awaik
但是这会自动在iOS中显示推送通知,即使你想在某些情况下避免。请指导。 - Awais Ahmad
1
我们需要把这段代码放在哪里,才能让它在用户每次启动应用程序时都运行? - Bruno Snickers

35

请查看以下示例。

https://github.com/FirebaseExtended/flutterfire/blob/master/packages/firebase_messaging/firebase_messaging/example/lib/main.dart

  @override
  void initState() {
    super.initState();
    FirebaseMessaging.instance
        .getInitialMessage()
        .then((RemoteMessage message) {
      if (message != null) {
        Navigator.pushNamed(context, '/message',
            arguments: MessageArguments(message, true));
      }
    });

    FirebaseMessaging.onMessage.listen((RemoteMessage message) {
      RemoteNotification notification = message.notification;
      AndroidNotification android = message.notification?.android;

      if (notification != null && android != null) {
        flutterLocalNotificationsPlugin.show(
            notification.hashCode,
            notification.title,
            notification.body,
            NotificationDetails(
              android: AndroidNotificationDetails(
                channel.id,
                channel.name,
                channel.description,
                // TODO add a proper drawable resource to android, for now using
                //      one that already exists in example app.
                icon: 'launch_background',
              ),
            ));
      }
    });

    FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
      print('A new onMessageOpenedApp event was published!');
      Navigator.pushNamed(context, '/message',
          arguments: MessageArguments(message, true));
    });
  }

26

在Jitesh的答案基础上,我认为需要实现getInitialMessage来使得当应用被终止时导航能够正常工作(替代onLaunch)。

    // workaround for onLaunch: When the app is completely closed (not in the background) and opened directly from the push notification
    FirebaseMessaging.instance.getInitialMessage().then((RemoteMessage message) {
      print('getInitialMessage data: ${message.data}');
      _serialiseAndNavigate(message);
    });

    // onMessage: When the app is open and it receives a push notification
    FirebaseMessaging.onMessage.listen((RemoteMessage message) {
      print("onMessage data: ${message.data}");
    });

    // replacement for onResume: When the app is in the background and opened directly from the push notification.
    FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
      print('onMessageOpenedApp data: ${message.data}');
      _serialiseAndNavigate(message);
    });

非常完美的解释,非常适合老用户!现在我明白了onMessageOpenedApp。 - Rajesh
谢谢,我无法在任何地方找到这个信息。 - Muklas
请在打印 message.data 后,它会给我一个空的映射表,我不知道为什么。 - Samuel
@Samuel,你是在 payload notification 中发送数据吗?尝试打印 message.notification 来验证是否正确处理了通知。 - luishromero
请问,当我关闭应用并点击通知时,为什么getInitialMessage返回空消息? - Ahmed Elsayed

2

经过一些测试,这是我的结论:

FirebaseMessaging.onMessageOpenedApp.listen((message)){} == "OLD" onResume() 只有在应用程序启动和/或在后台且通知被点击时才会激活

FirebaseMessaging.instance.getInitialMessage() == "OLD" onLaunch() 仅在应用程序被杀死且通知被点击时有效!


0

更新一:

FirebaseMessagingService 在应用程序开始时非常重要。为此,您需要遵循以下步骤: 首先声明此函数:

Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  debugPrint("Firebase Messaging firebase is initialized");
  await Firebase.initializeApp();
}

然后在应用程序的main(){}中调用此函数:

 FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);

然后您就可以使用这些函数:

FirebaseMessaging.onMessage 方法来获取消息

FirebaseMessaging.onMessage.listen((RemoteMessage message) {
      RemoteNotification notification = message.notification;
      AndroidNotification android = message.notification?.android;
    });

FirebaseMessaging.onMessageOpenedApp作为onLaunch和onResume处理程序的替代方案。

FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
      print('A new onMessageOpenedApp event was published!');
      Navigator.pushNamed(context, '/message',
          arguments: MessageArguments(message, true));
    });

0

事件处理:

事件处理已经重新设计,为开发者提供了更直观的API。基于前台的事件现在可以通过流进行访问:

FirebaseMessaging.onMessage返回一个流对象,当Flutter实例处于前台时接收到FCM有效负载时被调用,其中包含一个[RemoteMessage]。

FirebaseMessaging.onMessageOpenedApp返回一个[Stream]对象,在用户通过FCM显示的通知按下时被调用。这替代了之前的onLaunch和onResume处理程序。

FirebaseMessaging.onBackgroundMessage()设置后台消息处理程序,以在应用程序在后台或终止时触发。IosNotificationSettings:


0

是的,我做了所有那些 ^^ 而且一切都正常,除了在应用程序被终止时点击通知后的重定向。 我确保当应用程序被终止时,onMessageOpenedApp.listen() 不起作用。

证据是,我有一个屏幕,记录所有收到的通知以及在应用程序被终止时接收到的通知:

  • 已接收并显示
  • 持久化并显示在历史屏幕中

当应用程序被终止时,点击通知时无法触发 onMessageOpenedApp(就像 onLaunch() / onResume() 之前有效一样...)。

这就是为什么我问如何在新版本的 Firebase 中实现这一点的原因?


0
我知道关于.onLaunch()和.onResume()方法的更改。 它们已被替换为。
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
      print('A new onMessageOpenedApp event was published!');
      Navigator.pushNamed(context, '/message',
          arguments: MessageArguments(message, true));
    });

但是这只在应用程序仍然在后台运行时有效! 如果应用程序被杀死,它将无法工作。 如何实现这一点? 请问onLaunch()方法的“新”等效是什么?

你需要创建一个新问题。如果你担心它会被认为是重复的,那么请附带解释该问题与链接的区别。 - Mearaj
1
我已经在这里完成了: https://stackoverflow.com/questions/76522968/firebase-messaging-onmessageopenedapp-listen-doesnt-work-when-app-killed 谢谢 ^^ - Gob

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接