React Native中FCM+Notifee推送通知场景问题求助
React Native FCM + Notifee 问题解决方案
1. Android 应用完全退出后,notifee.getInitialNotification() 返回 null
原因
当 Android 应用被彻底杀死时,如果 FCM 推送的是包含 notification 字段的通知消息,系统会直接接管并显示通知,而非通过 Notifee 处理。Notifee 的 getInitialNotification() 仅能识别由 Notifee 自身展示的通知,因此无法捕获系统级通知的点击事件。
解决方案
方案一:同时检查 Firebase 和 Notifee 的初始通知
系统级通知的点击事件会被 Firebase 的 API 捕获,因此需要同时调用两者的初始通知获取方法:
// 替换原有的初始通知检查代码 const [firebaseInitial, notifeeInitial] = await Promise.all([ messaging().getInitialNotification(), notifee.getInitialNotification() ]); if (firebaseInitial) { logger.object('Firebase: 从退出状态通过通知打开应用', firebaseInitial); } if (notifeeInitial) { logger.object('Notifee: 从退出状态通过通知打开应用', notifeeInitial.notification); }
方案二:发送纯数据消息并通过 Notifee 展示
如果希望统一用 Notifee 处理所有通知(包括应用杀死状态),后端需发送纯数据消息(不含 notification 字段),并通过 setBackgroundMessageHandler 在后台触发 Notifee 展示通知(见问题2的实现)。此时 notifee.getInitialNotification() 就能正常捕获点击事件。
2. messaging().setBackgroundMessageHandler() 的作用及代码覆盖情况
核心作用
- 运行在无头 JavaScript 环境中,处理应用处于后台或完全杀死状态时收到的纯数据消息(不含
notification字段的 FCM 消息)。 - 可用于解析数据、调用 Notifee 展示通知、执行后台逻辑(无法更新 UI)。
当前代码覆盖情况
你的代码未实现该 handler,导致:
- 应用后台/杀死状态下收到的纯数据消息无法被处理,不会触发任何通知或逻辑。
- 仅系统级通知消息(含
notification字段)能被系统展示,但无法自定义处理逻辑。
实现示例
需在顶层作用域定义(不能放在异步函数内):
// 处理后台/杀死状态下的纯数据消息 messaging().setBackgroundMessageHandler(async remoteMessage => { logger.object('收到后台数据消息', remoteMessage); // 创建通知渠道(确保存在) const channelId = await notifee.createChannel({ id: 'General', name: 'General Notifications', importance: AndroidImportance.HIGH, }); // 通过 Notifee 展示通知 await notifee.displayNotification({ title: remoteMessage.data.title, body: remoteMessage.data.body, android: { channelId, importance: AndroidImportance.HIGH }, id: remoteMessage.data.notificationId, // 绑定业务通知ID actions: [{ title: '标记为已读', pressAction: { id: 'mark-as-read' } }] }); });
3. 为通知添加「标记为已读」选项
需在调用 notifee.displayNotification() 时配置 actions 字段,同时确保后台事件处理器已正确绑定逻辑(你的代码中已实现 onBackgroundEvent,只需补充通知配置)。
更新通知展示代码
修改 displayForegroundNotification 函数:
const displayForegroundNotification = async ( remoteMessage: FirebaseMessagingTypes.RemoteMessage ) => { logger.object('收到前台通知', remoteMessage.notification); const channelId = await notifee.createChannel({ id: 'General', name: 'General Notifications', importance: AndroidImportance.HIGH, }); try { await notifee.displayNotification({ title: remoteMessage.notification?.title, body: remoteMessage.notification?.body, // 绑定业务通知ID,用于后续标记已读和取消通知 id: remoteMessage.data?.notificationId || remoteMessage.messageId, android: { channelId, importance: AndroidImportance.HIGH, // Android 端添加操作按钮 actions: [{ title: '标记为已读', pressAction: { id: 'mark-as-read' } }] }, ios: { // iOS 端添加操作按钮,设置后台激活模式 actions: [{ title: '标记为已读', activationMode: 'background', // 无需打开应用即可执行 pressAction: { id: 'mark-as-read' } }] } }); } catch (error) { logger.error(`展示前台通知失败: ${error}`); } };
测试注意事项
通过 Postman 发送测试通知时,需在 data 字段中传入 notificationId,确保通知能正确绑定业务ID:
{ "to": "你的FCM Token", "notification": { "title": "测试通知", "body": "点击标记为已读" }, "data": { "notificationId": "test_123" } }
内容的提问来源于stack exchange,提问作者NoamKu
相关产品推荐
相关产品推荐

