React Native:应用后台/杀死状态下触发FCM通知页面的方法
解决React Native FCM后台/杀死状态下无法跳转通知页面的问题
我明白你遇到的困扰了——前台能正常跳转到TargetScreenPage,但后台或应用被杀死时就失效,这其实是FCM在不同运行状态下的通知处理逻辑差异导致的,下面给你一步步拆解解决方案:
核心原因分析
当应用处于前台时,所有FCM消息(不管是通知型还是数据型)都会直接触发FCMEvent.Notification事件,你的代码能正常捕获并执行跳转;但当应用在后台或被杀死时:
- 纯通知型消息会先由系统展示在通知栏,只有用户点击通知后应用才会启动,这时候初始的通知数据需要通过
getInitialNotification()来获取,而非实时的FCMEvent.Notification监听 - 纯数据型消息会直接触发事件,但系统不会自动展示通知,需要你手动创建本地通知
具体解决方案
1. 在应用启动时捕获初始通知(关键步骤)
你需要在应用入口组件(比如你的HomePage,或更上层的App组件)中,调用FCM.getInitialNotification()获取用户点击通知启动应用时的消息数据,再执行跳转。修改你的HomePage代码:
export default class HomePage extends Component { constructor(props){ super(props); this.state={ totalTarget: null, targetAchieved:null, message:null }; } componentDidMount() { // 监听前台实时通知 this.notificationListener = FCM.on(FCMEvent.Notification, async(notify)=>{ if(notify.local_notification){ // 本地通知逻辑 } if(notify.opened_from_tray){ this.props.navigation.navigate('TargetScreenPage') } if(Platform.OS==='android'){ switch(notify.NotificationType){ case NotificationType.Remote: notify.finish( RemoteNotificationResult.NewData ) break; case NotificationType.NotificationResponse: notify.finish(); break; case NotificationType.WillPresent: notify.finish(WillPresentNotificationResult.All) break; } } }); // 捕获后台/杀死状态下点击通知启动应用的初始数据 FCM.getInitialNotification().then(notify => { if (notify && notify.opened_from_tray) { // 确保navigation已初始化,若有延迟可加setTimeout或用全局navigation ref this.props.navigation.navigate('TargetScreenPage'); } }); // 监听token刷新 this.refreshTokenListener = FCM.on(FCMEvent.RefreshToken,(token)=>{ console.log(token); }) } componentWillUnmount() { // 移除监听避免内存泄漏 this.notificationListener.remove(); this.refreshTokenListener.remove(); } // ... 你的其他渲染逻辑 }
2. Android端配置点击行为
在AndroidManifest.xml的MainActivity标签内添加intent filter,匹配FCM通知中的click_action字段,确保点击通知能正确唤起应用并传递数据:
<activity android:name=".MainActivity" ...> <!-- 新增intent filter --> <intent-filter> <action android:name="OPEN_TARGET_SCREEN" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
发送REST通知时,需在data字段中指定click_action为OPEN_TARGET_SCREEN,示例请求体:
{ "to": "你的设备token", "notification": { "title": "测试通知", "body": "点击跳转目标页面" }, "data": { "click_action": "OPEN_TARGET_SCREEN", "自定义字段": "任意内容" } }
3. iOS端配置通知处理
在AppDelegate.m中确保正确传递通知数据到React Native层:
#import "FCM.h" // ... - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { [[FCM sharedInstance] didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler]; } // 处理通知点击事件 - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler { [[FCM sharedInstance] didReceiveNotificationResponse:response]; completionHandler(); }
4. 确保Navigation全局可用
如果HomePage不是顶层组件,可能出现navigation未初始化就调用跳转的问题,建议使用全局Navigation Ref:
在App.js中创建ref:
import { NavigationContainer } from '@react-navigation/native'; import { createStackNavigator } from '@react-navigation/stack'; const Stack = createStackNavigator(); export const navigationRef = React.createRef(); export default function App() { return ( <NavigationContainer ref={navigationRef}> <Stack.Navigator> <Stack.Screen name="HomePage" component={HomePage} /> <Stack.Screen name="TargetScreenPage" component={TargetScreenPage} /> </Stack.Navigator> </NavigationContainer> ); }
然后在获取初始通知时用ref跳转:
import { navigationRef } from './App'; // ... FCM.getInitialNotification().then(notify => { if (notify && notify.opened_from_tray) { navigationRef.current?.navigate('TargetScreenPage'); } });
验证步骤
发送测试通知时,确保:
- 应用处于后台或被杀死状态
- 通知包含
notification和data字段(纯data字段需手动创建本地通知) - 点击通知后应用能启动并自动跳转到
TargetScreenPage
内容的提问来源于stack exchange,提问作者Khushdeep Kaur
相关产品推荐
相关产品推荐

