Flutter集成firebase_messaging前台收通知无法跳转页面如何解决
问题原因
前台运行时FCM不会触发系统通知栏弹窗,你当前是通过flutter_local_notifications手动弹出通知,这类自定义弹出的通知点击事件不由FirebaseMessaging的onMessageOpenedApp回调处理,需要单独监听flutter_local_notifications的通知点击回调。
具体修改步骤
1. 封装公共跳转逻辑
将重复的页面跳转逻辑抽成公共方法,避免代码冗余,在首页State中添加如下方法:
// 抽离公共跳转方法 void _handleNotificationJump(Map<String, dynamic> data) async { if (loginState) { if (data['module'] == 'article') { var articleID = data['id']; Navigator.pushNamed(context, 'ArticleDetails', arguments: MessageArguments(RemoteMessage(data: data), true)); } else if (data['module'] == 'question') { var questionID = data['id']; Navigator.pushNamed(context, 'QuestionDetails', arguments: MessageArguments(RemoteMessage(data: data), true)); } else if (data['module'] == 'reservation') { Navigator.pushNamed(context, 'Reservations', arguments: MessageArguments(RemoteMessage(data: data), true)); } else if (data['module'] == 'job') { Navigator.pushNamed(context, 'Jobs', arguments: MessageArguments(RemoteMessage(data: data), true)); } else if (data['module'] == 'addresses') { Navigator.pushNamed(context, 'InterestedAddresses', arguments: MessageArguments(RemoteMessage(data: data), true)); } } else { Splash(); } }
2. 初始化时添加本地通知点击监听
修改main函数中flutterLocalNotificationsPlugin的初始化逻辑,添加通知点击回调:
if (!kIsWeb) { channel = const AndroidNotificationChannel( 'high_importance_channel', // id 'High Importance Notifications', // title 'This channel is used for important notifications.', // description importance: Importance.high, ); flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); // 新增:初始化本地通知并设置点击回调 await flutterLocalNotificationsPlugin.initialize( InitializationSettings( android: AndroidInitializationSettings('launcher_icon'), iOS: DarwinInitializationSettings(), ), // 通知点击时触发 onDidReceiveNotificationResponse: (NotificationResponse response) { if (response.payload != null) { // 把序列化的payload转成Map Map<String, dynamic> data = jsonDecode(response.payload!); // 直接调用公共跳转方法即可,若此处无法获取上下文可使用全局NavigatorKey或事件总线中转 } }, ); await flutterLocalNotificationsPlugin .resolvePlatformSpecificImplementation< AndroidFlutterLocalNotificationsPlugin>() ?.createNotificationChannel(channel); await FirebaseMessaging.instance .setForegroundNotificationPresentationOptions( alert: true, badge: true, sound: true, ); }
补充:如果使用的是
flutter_local_notifications低于9.0的旧版本,替换回调为onSelectNotification: (String? payload)即可。
3. 前台弹通知时传入payload
修改FirebaseMessaging.onMessage.listen中的show方法,传入序列化的消息data:
FirebaseMessaging.onMessage.listen((RemoteMessage message) { RemoteNotification notification = message.notification; AndroidNotification android = message.notification?.android; if (notification != null && android != null && !kIsWeb) { print(message.data); print('onMessage method'); flutterLocalNotificationsPlugin.show( notification.hashCode, notification.title, notification.body, NotificationDetails( android: AndroidNotificationDetails( channel.id, channel.name, channel.description, icon: 'launcher_icon', ), ), // 新增:传入序列化后的data作为payload payload: jsonEncode(message.data), ); } });
4. 优化原有逻辑复用公共方法
原来的onMessageOpenedApp和getInitialMessage回调可以直接调用抽离的公共方法,简化代码:
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) async { print('A new onMessageOpenedApp event was published!'); _handleNotificationJump(message.data); }); FirebaseMessaging.instance .getInitialMessage() .then((RemoteMessage message) async { if (message != null) { _handleNotificationJump(message.data); } });
注意事项
如果本地通知的点击回调在main函数中无法获取首页的context,可以通过以下两种方式处理:
- 定义全局
NavigatorKey,绑定到MaterialApp的navigatorKey属性,直接通过全局Key获取上下文跳转 - 使用事件总线(event_bus)在回调中发送事件,在首页State中监听事件触发跳转
内容的提问来源于stack exchange,提问作者Eslam Esmail
相关产品推荐
相关产品推荐

