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);
}
});
已调用后台处理程序,一切正常,但我不知道如何获取用于导航到新屏幕的 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);
}
});