在Flutter上点击后台通知时如何导航



单击后台FCM通知时,是否可以导航到指定路径?

我创建了一个Top Level函数,并将其添加到导航器路径中,但它不起作用,当点击后台通知时,它只打开应用程序

我想我发现了一个问题

现在,我将fcm配置从home page更改为splash screen。前台无法导航到页面,我认为这是因为Splash Screen不再可用。当我点击通知消息时,它会打开应用程序。

FCM配置

onBackgroundMessage: backgroundMessageHandler

顶级功能

Future<dynamic> backgroundMessageHandler(Map<String, dynamic> message) {
if (message.containsKey('data')) {
getIt<NavigationService>().navigateTo('/${message['data']['screen']}');
}
}

有效载荷

const payload: admin.messaging.MessagingPayload = {
notification:{
title: `New Enquiry`,
body:`${customerName} published to ${subName}`,
badge: '1',
sound: 'default'
},
data: {
click_action: `FLUTTER_NOTIFICATION_CLICK`,
sound: `default`,
status: `chat`,
screen: `homePage`
}
}

main.dart

GetIt getIt = GetIt.instance;
void main() {
setupLocator();
runApp(MyApp());
}

MaterialApp

return MaterialApp(
navigatorKey: NavigationService().navigatorKey,
onGenerateRoute: Router.generateRoute,
);

导航服务设置定位器

class NavigationService {
final GlobalKey<NavigatorState> navigatorKey =
new GlobalKey<NavigatorState>();
Future<dynamic> navigateTo(String routeName) {
return navigatorKey.currentState.pushNamed(routeName);
}
}
void setupLocator() {
getIt.registerLazySingleton(() => NavigationService());
}

您可以使用此功能在应用程序被终止时进行导航,并在后台中接收通知

FirebaseMessaging.instance
.getInitialMessage()
.then((RemoteMessage message) {
print("FirebaseMessaging.getInitialMessage");
if (message != null) {
Navigator.of(context).pushNamed('/call');
}
});

此功能仅在应用程序打开并获取最后一条消息时运行一次。

您可以在此文档中阅读更多信息:https://github.com/FirebaseExtended/flutterfire/blob/62e09975f9b3d14141585e62ddab6b98e667b7cf/docs/messaging/notifications.mdx

要处理来自后台状态的通知,可以使用FirebaseMessaging库公开的流。

FirebaseMessaging.onMessageOpenedApp.listen((remoteMessage) {
// Handle navigation or perform any logic here
});

我希望您已经配置了此处指定的firebase_messaging所需的本机端声明

根据您提供的有效载荷:

有效载荷

const payload: admin.messaging.MessagingPayload = {
notification:{
title: `New Enquiry`,
body:`${customerName} published to ${subName}`,
badge: '1',
sound: 'default'
},
data: {
click_action: `FLUTTER_NOTIFICATION_CLICK`,
sound: `default`,
status: `chat`,
screen: `homePage`
}
}

让你的onResume像这样,同样适用于onLaunch

onResume:

onResume: (Map<String, dynamic> message) {
if(SharedClassID.toString().contains(message['data']['classID']))
{

Navigator.push(context, MaterialPageRoute(builder: (context)=>BroadcastNotification()));
print("found");
}
else if(SharedClassID.toString().contains(message['data']['classID']))
{

Navigator.push(context, MaterialPageRoute(builder: (context)=>StudentHomework()));
print("found");
}
else
{
print("not found");
}

//print(message['data']['classID']+" onResume");
print('onResume: $message');
return;
}

我可以找出它不起作用的原因,因为在有效负载中,键是屏幕:'homePage',我可以注意到你没有传递classID所以它没有评估到你添加的if-else条件。

您更新if/else条件如下:

if(message['data']['screen'] == 'homePage')
{
//TODO: route

}else if(message['data']['screen'] == 'homeWorkPage'){
//TODO: route
}

如果要基于SharedClassId进行路由,则在有效负载和路由中传递classId。示例片段:

if(message['data']['classId'] == SharedClassId)
{
//TODO: route

}else if(message['data']['classId'] == SharedClassId){
//TODO: route
}

在该示例中,我使用类id等共享首选项数据来检查通知数据是否包含该类id,然后它可以导航到特定的屏幕

void registerNotification() {
_firebaseMessaging.requestNotificationPermissions(
const IosNotificationSettings(sound: true, badge: true, alert: true),
);
_firebaseMessaging.configure(onMessage: (Map<String, dynamic> message) {
print('onMessage: $message');
// print(message['data']['classID']+" onMessage");
if(SharedClassID.toString().contains(message['data']['classID']))
{

Navigator.push(context, MaterialPageRoute(builder: 
(context)=>BroadcastNotification()));
print("found");
}

else if(SharedClassID.toString().contains(message['data']['classID']) )
{

Navigator.push(context, MaterialPageRoute(builder: (context)=>MuseGalaryNew()));
print("found");
}
else
{
print("not found");
}
return;
}, onResume: (Map<String, dynamic> message) {
if(SharedClassID.toString().contains(message['data']['classID']))
{

Navigator.push(context, MaterialPageRoute(builder: (context)=>BroadcastNotification()));
print("found");
}
else if(SharedClassID.toString().contains(message['data']['classID']))
{

Navigator.push(context, MaterialPageRoute(builder: (context)=>StudentHomework()));
print("found");
}
else
{
print("not found");
}

//print(message['data']['classID']+" onResume");
print('onResume: $message');
return;
}, onLaunch: (Map<String, dynamic> message) {
if(SharedClassID.toString().contains(message['data']['classID'])  )
{
Navigator.push(context, MaterialPageRoute(builder: (context)=>BroadcastNotification()));
print("found");
}
else if(SharedClassID.toString().contains(message['data']['classID']))
{
Navigator.push(context, MaterialPageRoute(builder: (context)=>StudentHomework()));
print("found");
}
else
{
print("not found");
}
return;
});
}

截至2021年8月的最新代码。首先,您的项目dart版本和firebase插件版本是集成firebase通知的重要内容。如果您使用的是较低版本,那么您可能会遇到一些问题。对于我的flutter项目,我正在使用最新的空安全Firebase消息插件。如果你使用Flutter messaging 10.0.4或更高版本,那么你不需要在android清单文件上添加任何元数据。你可以在这里看到完整的代码。

firebase_messaging: ^10.0.4
firebase_core: ^1.4.0
flutter_local_notifications: ^8.1.1

如果flutter应用程序关闭,那么将调用以下代码。它将只被调用一次&您应该将click_action提供为";FLUTTER_ NOTIFICATION_;作为firebase控制台云消息窗口上的自定义数据。

// when app is closed and it will be called only once
FirebaseMessaging.instance.getInitialMessage().then((RemoteMessage? message) {
print("fireabse closed app msg");
if (message != null) {
print( " firebase msg received closed add "+message.data.toString());
Navigator.push(context, MaterialPageRoute(builder: (context){ return product(prodid: message.data["prodid"]);}));
/*  Navigator.pushNamed(context, '/message',
arguments: MessageArguments(message, true));
*/
}
});

要在状态栏上显示通知图标,请使用以下代码。

FirebaseMessaging.onMessage.listen((RemoteMessage message) {
RemoteNotification? notification = message.notification;
AndroidNotification? android = message.notification?.android;
print(" firebase msg - "+message.data.length.toString());
if (notification != null && android != null) {
print("firebase msg body "+ notification.body.toString());
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: 'noti_icon',
color: Colors.red
),
));

}
});

相关内容

  • 没有找到相关文章

最新更新