react-native-firebase messaging中onInitialNotification始终返回null问题
React Native Firebase Messaging 退出状态打开应用时 remoteMessage 返回 null 的问题
问题详情
使用 react-native-firebase messaging 时,应用从完全退出状态被通知唤起,getInitialNotification 方法能正常触发,但返回的 remoteMessage 始终为 null。通知可正常发送并打开应用,但无法实现点击通知跳转指定页面的需求。
现有代码
客户端消息处理代码
import messaging from '@react-native-firebase/messaging'; const Root = () => { useEffect(() => { messaging().setBackgroundMessageHandler(async remoteMessage => { console.log('Message handled in the background!', remoteMessage); }); messaging() .getInitialNotification() .then(remoteMessage => { console.log( 'Notification caused app to open from quit state:', remoteMessage, ); }); }, []); ... };
服务端消息发送代码
admin .firestore() .collection('users') .doc(change.after.data().userKey) .get() .then(doc => { admin.messaging().send({ token: doc.data().fcmToken, notification: { title: 'You have a new Comment', body: 'Check out your post now!', }, data: { screen: 'Profile', // params: JSON.stringify(change.after.data()), // params: JSON.stringify(params), }, }); });
问题原因与解决方案
1. iOS 推送负载格式缺陷
iOS 在应用完全退出状态下,仅当推送负载包含特定的 APNs 配置时,getInitialNotification 才能获取到完整的 remoteMessage(包括 data 字段)。当前发送的推送仅包含 notification 和 data,缺少 APNs 必要配置,导致数据无法被传递到初始通知对象中。
修改服务端推送代码,添加 APNs 配置:
admin.messaging().send({ token: doc.data().fcmToken, notification: { title: 'You have a new Comment', body: 'Check out your post now!', }, data: { screen: 'Profile', // 保留自定义参数 }, apns: { payload: { aps: { 'content-available': 1, // 标记为支持后台处理,确保数据被携带 }, }, headers: { 'apns-priority': '5', // 降低优先级避免被系统节流,确保送达 'apns-push-type': 'alert', }, }, });
2. iOS 项目配置检查
- 开启 Remote Notifications 后台模式:打开 Xcode,进入项目
Signing & Capabilities->Background Modes,勾选Remote notifications。 - 验证 Firebase 代理配置:在项目
Info.plist中添加FirebaseAppDelegateProxyEnabled键,值设为YES,确保 Firebase 能正确拦截通知点击事件。
3. 客户端代码优化
结合 onNotificationOpenedApp(处理后台状态唤起)和 getInitialNotification(处理退出状态唤起),统一导航逻辑:
import messaging from '@react-native-firebase/messaging'; import { useNavigation } from '@react-navigation/native'; const Root = () => { const navigation = useNavigation(); useEffect(() => { // 监听后台状态下点击通知 const unsubscribeBackground = messaging().onNotificationOpenedApp(remoteMessage => { handleNavigation(remoteMessage); }); // 处理退出状态下点击通知 messaging() .getInitialNotification() .then(remoteMessage => { if (remoteMessage) { handleNavigation(remoteMessage); } }); return () => { unsubscribeBackground(); }; }, [navigation]); // 统一处理页面跳转 const handleNavigation = (remoteMessage) => { const targetScreen = remoteMessage?.data?.screen; if (targetScreen) { navigation.navigate(targetScreen); } }; ... };
4. 测试关键注意事项
- 必须使用 iOS 真机测试:模拟器无法完全模拟退出状态下的推送行为。
- 测试前完全退出应用:彻底划掉后台应用,避免后台缓存导致的异常。
文档参考(翻译自 react-native-firebase 官方文档)
getInitialNotification()用于获取触发应用从完全退出状态启动的通知。只有当用户通过点击通知横幅启动应用时,该方法才会返回对应的远程消息对象;若应用通过其他方式(如点击图标)启动,则返回 null。在 iOS 平台上,如果推送仅包含notification字段而未配置 APNs 相关参数,可能导致无法获取完整的消息数据。
内容的提问来源于stack exchange,提问作者Tyler.G
相关产品推荐
相关产品推荐

