React Native Notifee点击通知跳转指定页面问题(含前后台场景)
问题
我在React Native应用里集成了Firebase推送通知,用Notifee库展示通知,现在通过FCM发送数据消息(不是通知消息),能正常接收通知。前台点击通知跳转指定页面没问题,但后台/静默模式下点击通知无法跳转。相关代码如下:
前台事件处理器
export function foregroundEvent() { return notifee.onForegroundEvent(({ type, detail }) => { switch (type) { case EventType.DISMISSED: console.log('<<<---------User dismissed notification--------->>>'); break; case EventType.PRESS: setTimeout(() => { navigationServices.navigate(navigationStrings.APPROVAL) }, 1200) console.log('<<<---------User pressed notification--------->>>'); break; } }); }
后台事件处理器(index.js)
/* eslint-disable prettier/prettier */ /** * @format */ import {AppRegistry} from 'react-native'; import messaging from '@react-native-firebase/messaging'; import App from './App'; import {name as appName} from './app.json'; import 'react-native-gesture-handler'; import { onDisplayNotification } from './src/utils/notifeeServices'; import notifee, { EventType } from '@notifee/react-native' import navigationServices from './src/utils/navigationServices'; import navigationStrings from './src/navigations/navigationStrings'; // fcm Register background handler messaging().setBackgroundMessageHandler(async remoteMessage => { console.log('Message handled in the background!', remoteMessage); await onDisplayNotification(remoteMessage); }); notifee.onBackgroundEvent(async ({ type, detail }) => { const { notification, pressAction } = detail; console.log(type ); if (type === EventType.ACTION_PRESS) { console.log('user pressed notification background/quite mode====>'); setTimeout(() => { return navigationServices.navigate(navigationStrings.ACCOUNT_FINANCE) }, 1200) await notifee.cancelNotification(notification.id); } }); AppRegistry.registerComponent(appName, () => App);
通知展示函数(onDisplayNotification)
export async function onDisplayNotification(data:any) { // Request permissions (required for iOS) if (Platform.OS === 'ios') { await notifee.requestPermission(); } // Create a channel (required for Android) const channelId = await notifee.createChannel({ id: data?.data?.channel_id, name: data?.data?.channel_name, sound: data?.data?.sound_name, // importance: AndroidImportance.HIGH, }); // Display a notification await notifee.displayNotification({ title: data?.data?.title, body: data?.data?.body, android: { channelId, smallIcon: 'ic_launcher', color: BlueColor, pressAction: { id: 'default', launchActivity: 'default' }, }, }); }
解决方案
1. 修正后台事件的触发类型
后台/静默模式下,普通点击通知的事件类型是EventType.PRESS,而非EventType.ACTION_PRESS(后者针对通知上的自定义按钮点击)。同时后台无法直接调用导航服务(导航实例未初始化),需先把跳转目标存入本地存储:
// 先导入AsyncStorage import AsyncStorage from '@react-native-async-storage/async-storage'; // 修改后台事件处理器 notifee.onBackgroundEvent(async ({ type, detail }) => { const { notification } = detail; console.log('后台事件类型:', type); if (type === EventType.PRESS) { console.log('后台/静默模式下点击了通知'); // 存储待跳转页面 await AsyncStorage.setItem('pendingNavigation', navigationStrings.ACCOUNT_FINANCE); await notifee.cancelNotification(notification.id); } });
2. App启动时处理待跳转任务
后台点击通知会唤起App,在根组件启动时检查本地存储的跳转目标,执行跳转后清空存储:
// App.js 示例 import React, { useEffect } from 'react'; import AsyncStorage from '@react-native-async-storage/async-storage'; import navigationServices from './src/utils/navigationServices'; function App() { useEffect(() => { const handlePendingNavigation = async () => { const targetScreen = await AsyncStorage.getItem('pendingNavigation'); if (targetScreen) { // 等待导航实例初始化完成 setTimeout(() => { navigationServices.navigate(targetScreen); AsyncStorage.removeItem('pendingNavigation'); }, 800); } }; handlePendingNavigation(); }, []); return <YourNavigationContainer />; } export default App;
3. 完善通知跨平台配置
补充iOS端的通知配置,确保点击能正确唤起App;同时确认Android端pressAction配置正确:
// 修改onDisplayNotification里的displayNotification配置 await notifee.displayNotification({ title: data?.data?.title, body: data?.data?.body, android: { channelId, smallIcon: 'ic_launcher', color: BlueColor, pressAction: { id: 'default', launchActivity: 'default' }, }, ios: { foregroundPresentationOptions: { alert: true, badge: true, sound: true, }, pressAction: { id: 'default', }, }, });
4. 确保导航服务全局可用
确认你的navigationServices基于导航容器ref创建,保证App启动后能获取有效导航实例:
// navigationServices.js 示例 import { NavigationContainerRef } from '@react-navigation/native'; export let navigationRef: NavigationContainerRef; export function setNavigationRef(ref: NavigationContainerRef) { navigationRef = ref; } export function navigate(name: string, params?: any) { if (navigationRef.isReady()) { navigationRef.navigate(name, params); } } // 在导航容器中绑定ref <NavigationContainer ref={setNavigationRef}> {/* 你的导航栈 */} </NavigationContainer>
内容的提问来源于stack exchange,提问作者Md. Al Amin
相关产品推荐
相关产品推荐

