Flutter Firebase 消息传递:在收到后台通知时打开一个新屏幕

Flutter Firebase messaging : open a new screen on background notification received

已调用后台处理程序,一切正常,但我不知道如何获取用于导航到新屏幕的 BuildContext 实例。我有这个处理程序


Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
    var notificationData = message.data;
    var view = notificationData['view'];

    if(view == 'MessagesScreen') {
        Map<String, dynamic> videoData = json.decode(
            notificationData['video_data']);
        VideoItem videoItem = VideoItem.fromJson(videoData);

       Navigator.pushNamed(context, '/playerScreen', arguments:{videoItem});
    } else {
        view = '/$view';
        Navigator.pushNamed(context, view);
    }

    return Future<void>.value();
}

是这样叫的

await Firebase.initializeApp();
FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler);

我正在使用 Firebase 消息传递:9.1.2

知道如何实现吗?

感谢

这种行为是不可能直接发生的。后台程序处理程序作为一个新的隔离生成,您不能在其中执行任何 UI 相关操作。

您可以通过侦听来自 UI 线程的端口并从后台 isolate

将数据发送到该端口来执行隔离通信

在 UI 线程上收听:

  ReceivePort _port = ReceivePort();
     IsolateNameServer.registerPortWithName(
     _port.sendPort, 'port_name');
     _port.listen((dynamic data) {
        /// navigate here
     }

发送消息,在 backgroundHandler 中:

final SendPort send =
  IsolateNameServer.lookupPortByName('port_name');
 send.send(true);

如果您想在应用程序终止时用户点击通知时进行导航,请尝试以下操作:

FirebaseMessaging.instance
    .getInitialMessage()
    .then((RemoteMessage? message) {
  if (message == null) return;

  var notificationData = message.data;
  var view = notificationData['view'];

  if(view == 'MessagesScreen') {
      Map<String, dynamic> videoData = json.decode(
          notificationData['video_data']);
      VideoItem videoItem = VideoItem.fromJson(videoData);

    Navigator.pushNamed(context, '/playerScreen', arguments:{videoItem});
  } else {
      view = '/$view';
      Navigator.pushNamed(context, view);
  }
  
});

检查这个例子:https://github.com/FirebaseExtended/flutterfire/blob/master/packages/firebase_messaging/firebase_messaging/example/lib/main.dart#L116