Flutter中点击推送通知跳转至指定页面的实现方案
实现Firebase通知点击跳转至指定页面
要实现点击通知跳转至SecondPage(data: data),需要覆盖应用冷启动、后台运行、前台运行三种场景,以下是具体修改方案:
1. 全局导航键配置
首先在main.dart中定义全局导航键,用于在非Widget环境中获取上下文完成页面跳转:
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
然后在MaterialApp中绑定该键:
class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( navigatorKey: navigatorKey, // 绑定全局导航键 title: 'Flutter Demo', home: const FirstPage(), // 你的应用初始页面 ); } }
2. 完善NotificationsHelper的通知初始化回调
修改initializeNotification方法,添加通知点击后的回调逻辑,从payload中解析数据并跳转:
static Future<void> initializeNotification() async { AndroidInitializationSettings androidInitializationSettings = const AndroidInitializationSettings('@mipmap/ic_launcher'); await _notificationsPlugin.initialize( InitializationSettings( android: androidInitializationSettings, iOS: const DarwinInitializationSettings(), ), // 添加通知点击回调 onDidReceiveNotificationResponse: (NotificationResponse response) { // 解析推送携带的自定义数据 Map<String, dynamic>? data = jsonDecode(response.payload ?? '{}'); if (data != null && navigatorKey.currentContext != null) { Navigator.push( navigatorKey.currentContext!, MaterialPageRoute( builder: (context) => SecondPage(data: data), ), ); } }, ); }
3. 修改前台通知展示逻辑,携带数据payload
更新onMessage方法,在展示本地通知时传入推送的自定义数据作为payload:
static void onMessage(BuildContext context, RemoteMessage message) { RemoteNotification? notification = message.notification; AndroidNotification? androidNotification = message.notification?.android; AppleNotification? appleNotification = message.notification?.apple; if (notification == null) return; // 将推送的data转为JSON字符串作为payload String payload = jsonEncode(message.data); // 调整判断逻辑,兼容单平台情况 if (androidNotification != null || appleNotification != null) { _notificationsPlugin.show( notification.hashCode, notification.title, notification.body, _notificationDetails(), payload: payload, // 携带自定义数据 ); } }
4. 处理后台点击通知场景
修改onMessageOpenedApp方法,替换原弹窗逻辑为页面跳转:
static void onMessageOpenedApp(BuildContext context, RemoteMessage? message) { if (message == null) return; // 获取推送的自定义数据 Map<String, dynamic> data = message.data; Navigator.push( context, MaterialPageRoute( builder: (context) => SecondPage(data: data), ), ); }
然后在main.dart中注册该回调:
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) { if (navigatorKey.currentContext != null) { NotificationsHelper.onMessageOpenedApp(navigatorKey.currentContext!, message); } });
5. 处理应用冷启动场景
在main函数中处理冷启动时的初始消息,完成跳转:
Future<void> main() async { WidgetsFlutterBinding.ensureInitialized(); await FirebaseHelper.setupFirebase(); await Firebase.initializeApp(); // 处理冷启动时的初始消息 RemoteMessage? initialMessage = await FirebaseMessaging.instance.getInitialMessage(); if (initialMessage != null) { // 延迟执行,确保MaterialApp已初始化完成 WidgetsBinding.instance.addPostFrameCallback((_) { if (navigatorKey.currentContext != null) { Navigator.push( navigatorKey.currentContext!, MaterialPageRoute( builder: (context) => SecondPage(data: initialMessage.data), ), ); } }); } final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); try { await NotificationsHelper.initializeNotification(); FirebaseMessaging.onBackgroundMessage(myBackgroundMessageHandler); await FirebaseMessaging.instance .setForegroundNotificationPresentationOptions( alert: true, badge: true, sound: true, ); // 注册后台点击通知回调 FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) { if (navigatorKey.currentContext != null) { NotificationsHelper.onMessageOpenedApp(navigatorKey.currentContext!, message); } }); } catch (e) { if (kDebugMode) { print(e.toString()); } } runApp(const MyApp()); }
注意事项
推送消息时,需要在data字段中携带传递给SecondPage的内容,示例推送结构:
{ "data": { "detailTitle": "通知详情标题", "detailContent": "完整的通知内容展示" }, "notification": { "title": "推送标题", "body": "推送预览内容" } }
内容的提问来源于stack exchange,提问作者Tpp
相关产品推荐
相关产品推荐

