Flutter点击Firebase推送通知路由时应用终止状态参数为null如何解决
问题原因
- Firebase Cloud Messaging 的
data字段要求所有值必须为字符串类型,如果你的sentby变量是数字、布尔值等非字符串类型,在应用被冷启动(终止状态打开)时,非字符串类型的参数会被系统丢弃,导致取到null。 - 推送优先级不足,安卓系统在应用被终止时,会优先处理高优先级推送,低优先级推送的
data字段可能被截断丢失。 - 未正确配置安卓端的
clickAction对应的intent-filter,导致冷启动时系统无法正确把完整的data数据传递给Flutter层。 - 路由跳转使用的context失效,或者
getInitialMessage调用时机太晚,导致参数还没拿到就已经执行了路由逻辑。
解决方案
1. 修正云函数推送配置
强制把data字段的所有值转成字符串,同时添加推送优先级配置,确保data字段完整传递:
const payload = admin.messaging.MessagingPayload = { data : { 'type' : 'msg', 'route' : 'chat-screen', 'argument' : sentby.toString(), // 强制转为字符串 }, notification : { title : senderData.user_name, body: original.message, image: notificationIcon, android_channel_id : "Finiso", channel_id : "Finiso", clickAction : 'FLUTTER_NOTIFICATION_CLICK', }, // 新增安卓高优先级配置 android: { priority: 'high', contentAvailable: true, }, // 可选:新增iOS配置,避免iOS端出现同类问题 apns: { payload: { aps: { contentAvailable: true, } } } }
2. 配置安卓端IntentFilter
打开android/app/src/main/AndroidManifest.xml,找到MainActivity节点,添加对应clickAction的intent-filter:
<activity android:name=".MainActivity" <!-- 原有配置保留 --> > <!-- 原有intent-filter保留 --> <intent-filter> <action android:name="FLUTTER_NOTIFICATION_CLICK" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
3. 使用全局导航键避免Context失效
定义全局导航键,确保冷启动时路由跳转可以拿到有效的上下文:
// main.dart 全局位置定义导航键 final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>(); void main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(); FirebaseMessaging.onBackgroundMessage(backgroundHandler); // 提前初始化getInitialMessage监听 FirebaseMessaging.instance.getInitialMessage().then((message) async { if (message != null) { // 此处可以打印完整data确认参数是否存在 print("冷启动通知参数:${message.data}"); routeNotification(message); } }); runApp(MyApp()); } // MaterialApp绑定导航键 class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( navigatorKey: navigatorKey, // 其他配置:主题、路由表等 ); } } // 调整路由函数 void routeNotification(RemoteMessage message) { final routeName = message.data['route']; if (routeName == ActivityFeed.routeName) { navigatorKey.currentState?.pushNamed(ActivityFeed.routeName); } else if (message.data['type'] == 'msg') { navigatorKey.currentState?.pushNamed( routeName, arguments: message.data['argument'], ); } }
4. 其他排查项
- 升级
firebase_messaging到最新稳定版,旧版本存在冷启动参数丢失的已知bug。 - 确认
data字段的键名没有拼写错误,比如云函数写的是argument,Flutter端取值时不要写成arguments。
内容的提问来源于stack exchange,提问作者Milind Lakhwani
相关产品推荐
相关产品推荐

