Expo环境下iOS端onNotificationOpenedApp与getInitialNotification失效问题
FCM消息处理问题排查与修复方案
一、setBackgroundMessageHandler 无法触发的修复
- 平台配置检查
- Android:后台消息必须是纯数据消息(不含
notification字段),系统才会交给setBackgroundMessageHandler处理;若带notification字段,系统会直接展示通知,不走该回调。同时确认AndroidManifest.xml中FirebaseMessagingService配置正确,无自定义服务冲突。 - iOS:在Xcode的Signing & Capabilities中开启Background Modes并勾选"Remote notifications";后台推送的apns-push-type需设为
background,apns-priority设为5(设为10会被当作前台通知处理)。
- Android:后台消息必须是纯数据消息(不含
- 代码位置修正
setBackgroundMessageHandler必须放在React组件外部(如App.js最顶部),不能在useEffect或组件内部定义——后台消息触发时React组件尚未初始化,内部定义的回调无法被调用。 - 依赖版本兼容
检查@react-native-firebase/messaging和@notifee/react-native的版本,确保两者兼容(建议使用最新稳定版),版本冲突可能导致回调不触发。
二、iOS端onNotificationOpenedApp和getInitialNotification失效修复
- 通知类型校验
这两个方法仅对带notification字段的通知消息生效;若发送的是纯数据消息,系统不展示通知,用户无法点击,自然不会触发回调。 - 重新确认通知权限
确保用户已授权通知的alert、badge、sound权限,且开启了"Allow Notifications"和"Show in Notification Center"。可在代码中主动请求权限:
import messaging from '@react-native-firebase/messaging'; async function requestNotificationPermission() { const authStatus = await messaging().requestPermission(); const enabled = authStatus === messaging.AuthorizationStatus.AUTHORIZED || authStatus === messaging.AuthorizationStatus.PROVISIONAL; if (enabled) console.log('Notification permission granted'); }
- APNs配置检查
确认Xcode中的推送证书有效,推送环境(开发/生产)与后台发送环境一致;使用Firebase Console测试时,需选择对应环境的设备。 - 避免回调重复注册
确保onNotificationOpenedApp和getInitialNotification仅注册一次,不要在多个useEffect中重复定义,否则会覆盖原有回调。 - notifee回调冲突处理
由于你使用notifee展示通知,iOS端的通知点击事件可能被notifee的onBackgroundEvent接管,导致FCM原生回调失效。可统一在notifee的回调中处理点击逻辑,或在FCM的两个回调中同步跳转逻辑,确保两端行为一致。
三、代码优化建议
- 调整setBackgroundMessageHandler位置
将其移至组件外部,确保后台能正常调用:
// App.js 顶部全局位置 import messaging from '@react-native-firebase/messaging'; import notifee from '@notifee/react-native'; messaging().setBackgroundMessageHandler(async (remoteMessage) => { console.log("Message handled in the background!", remoteMessage); await notifee.incrementBadgeCount(); }); // 后续定义App组件 function App() { // ... 组件逻辑 }
- 统一通知点击逻辑
同步FCM回调与notifee回调的处理逻辑,避免两端行为不一致:
React.useEffect(() => { // 后台状态点击通知打开App messaging().onNotificationOpenedApp(async (remoteMessage) => { const orderId = remoteMessage.data?.orderId; if (orderId && isAuthenticated) { navigate("order", { id: Number(orderId) }); } }); // 杀死状态点击通知打开App messaging().getInitialNotification().then(async (remoteMessage) => { if (remoteMessage?.data?.orderId && isAuthenticated) { navigate("order", { id: Number(remoteMessage.data.orderId) }); } }); // ... 其他FCM监听逻辑 }, [isAuthenticated, navigate]);
- 确认数据字段传递
后台发送通知时,确保orderId等业务数据放在FCM的data字段下,而非notification字段,避免解析错误。
内容的提问来源于stack exchange,提问作者Arjen
相关产品推荐
相关产品推荐

