使用Flutter Local Notifications与FCM处理应用终止状态
Flutter FCM终止状态下通知点击跳转指定页面的解决方案
应用终止状态下点击通知属于冷启动场景,此时onSelectNotification回调不会触发,也无法依赖onBackgroundMessage的后续逻辑处理路由跳转,必须在App初始化阶段获取启动时的初始消息来完成跳转。
核心解决步骤
1. 初始化阶段获取冷启动的初始消息
在main函数中调用FirebaseMessaging.instance.getInitialMessage(),获取App因点击通知而冷启动的消息数据,根据消息中的路由信息设置初始页面或后续跳转。
void main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(); // 处理冷启动时的通知点击事件 RemoteMessage? initialMessage = await FirebaseMessaging.instance.getInitialMessage(); String initialRoute = '/'; if (initialMessage != null) { // 从FCM消息的data字段读取预设的路由信息 initialRoute = initialMessage.data['target_route'] ?? '/'; } runApp(MyApp(initialRoute: initialRoute)); } class MyApp extends StatelessWidget { final String initialRoute; const MyApp({super.key, required this.initialRoute}); @override Widget build(BuildContext context) { return MaterialApp( initialRoute: initialRoute, routes: { '/': (context) => const HomePage(), '/product_detail': (context) => const ProductDetailPage(), // 注册你的其他路由 }, ); } }
2. 确保通知消息携带路由数据
无论前台onMessage还是后台onBackgroundMessage中调用flutterLocalNotificationsPlugin.show()时,都要将路由信息传入payload参数,同时确保FCM推送的消息data字段包含该路由信息(冷启动时初始消息会读取data内容)。
后台消息处理示例:
Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async { await Firebase.initializeApp(); await flutterLocalNotificationsPlugin.initialize( InitializationSettings( android: AndroidInitializationSettings('@mipmap/ic_launcher'), iOS: DarwinInitializationSettings(), ), // 处理前台/后台状态下的通知点击跳转 onSelectNotification: (payload) async { if (payload != null && navigatorKey.currentContext != null) { Navigator.pushNamed(navigatorKey.currentContext!, payload); } }, ); // 从FCM消息data中提取路由 String targetRoute = message.data['target_route'] ?? '/'; await flutterLocalNotificationsPlugin.show( message.hashCode, message.notification?.title, message.notification?.body, NotificationDetails( android: AndroidNotificationDetails( 'notification_channel', '通知渠道', importance: Importance.max, priority: Priority.high, ), ), payload: targetRoute, ); }
3. 全局导航键配置(可选)
如果需要在非Widget环境中触发页面跳转,可配置全局navigatorKey:
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>(); // 在MaterialApp中绑定 MaterialApp( navigatorKey: navigatorKey, // ...其他配置 ); // 跳转时使用 navigatorKey.currentState?.pushNamed(targetRoute);
关键注意事项
- 冷启动场景下,
onSelectNotification回调不会执行,必须依赖getInitialMessage()获取启动消息。 - FCM推送消息时,务必将路由信息放在
data字段中,而非notification字段(notification字段仅用于展示内容,冷启动时无法直接读取)。 - 前台和后台状态下的通知点击跳转,仍可通过
onSelectNotification正常处理。
内容的提问来源于stack exchange,提问作者A.Usama
相关产品推荐
相关产品推荐

