You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native云消息:后台/静默模式双通知及Notifee跳转问题

React Native FCM+Notifee 双通知及点击跳转问题解决

问题核心

  1. 应用在后台/静默模式下会收到两条通知:一条由Firebase自动展示,一条由Notifee生成
  2. Notifee通知点击后无法打开应用,也无法跳转指定页面;Firebase通知则正常

一、解决双通知问题

原因

当推送消息包含notification字段时,Firebase在后台/静默状态会自动触发系统通知,同时你的setBackgroundMessageHandler又调用Notifee展示了一条通知,导致重复。

解决方案

1. 修改推送消息格式

去掉notification字段,把标题、内容全部放到data中(纯数据消息):

{
    "registration_ids": ["device-tokens......"],
    "data": {
        "channel_id": "demo-channel",
        "channel_name": "demo-channel",
        "sound_name": "default",
        "title": "Test notification title!",
        "body": "Test notificaton body",
        "redirect_to": "Menu" // 新增跳转目标标识
    }
}

2. 更新onDisplayNotification函数

从data字段读取标题内容,同时配置通知的点击动作:

export async function onDisplayNotification(data: any) {
    if (Platform.OS === 'ios') {
        await notifee.requestPermission();
    }

    const channelId = await notifee.createChannel({
        id: data?.data?.channel_id,
        name: data?.data?.channel_name,
        sound: data?.data?.sound_name,
    });

    await notifee.displayNotification({
        title: data?.data?.title,
        body: data?.data?.body,
        android: {
            smallIcon: 'ic_launcher',
            channelId,
            color: BlueColor,
            // 配置Android点击动作,必须设置才能打开应用
            pressAction: {
                id: 'default',
            },
        },
        ios: {
            foregroundPresentationOptions: {
                alert: true,
                badge: true,
                sound: true,
            },
            // iOS也必须配置pressAction
            pressAction: {
                id: 'default',
            },
        },
        // 携带消息数据,点击时可读取跳转信息
        data: data?.data,
    });
}

二、实现Notifee通知点击跳转

1. 添加Notifee通知点击监听

修改notificationListner函数,新增Notifee的前后台事件监听:

import AsyncStorage from '@react-native-async-storage/async-storage';
import { EventType } from '@notifee/react-native';

export async function notificationListner() {
    // 前台FCM消息监听(保留原逻辑)
    const unsubscribe = messaging().onMessage(async remoteMessage => {
        console.log('A new FCM message arrived!', remoteMessage);
        await onDisplayNotification(remoteMessage);
    });

    // 前台状态下的Notifee通知点击
    notifee.onForegroundEvent(async ({ type, detail }) => {
        if (type === EventType.PRESS) {
            const redirectData = detail.notification.data;
            console.log('前台点击Notifee通知:', redirectData);
            // 直接跳转指定页面
            if (redirectData?.redirect_to === 'Menu') {
                NavigationService.navigate('Menu', { data: redirectData });
            }
        }
    });

    // 后台/关闭状态下的Notifee通知点击
    notifee.onBackgroundEvent(async ({ type, detail }) => {
        if (type === EventType.PRESS) {
            const redirectData = detail.notification.data;
            console.log('后台点击Notifee通知:', redirectData);
            // 后台无法直接跳转,存储参数等应用启动后处理
            await AsyncStorage.setItem('notificationRedirect', JSON.stringify(redirectData));
        }
    });

    // 应用从关闭状态启动时,检查跳转参数
    messaging()
        .getInitialNotification()
        .then(async () => {
            const redirectStr = await AsyncStorage.getItem('notificationRedirect');
            if (redirectStr) {
                const redirectData = JSON.parse(redirectStr);
                if (redirectData?.redirect_to === 'Menu') {
                    // 延迟确保导航初始化完成
                    setTimeout(() => {
                        NavigationService.navigate('Menu', { data: redirectData });
                    }, 1000);
                }
                // 用完删除参数
                await AsyncStorage.removeItem('notificationRedirect');
            }
        });

    return unsubscribe;
}

2. 关键注意点

  • Android:必须配置pressAction.id = 'default'才能触发打开应用的动作
  • iOS:pressAction是必填项,同时确保Info.plist中已开启通知权限
  • 导航跳转:确保NavigationService已正确配置,支持非组件环境调用导航
  • 后台处理:后台事件中不能直接调用导航,需通过AsyncStorage暂存参数,待应用启动后处理

三、后台处理器保持原逻辑即可

messaging().setBackgroundMessageHandler(async remoteMessage => {
    await onDisplayNotification(remoteMessage);
    console.log('Message handled in the background!', remoteMessage);
});

内容的提问来源于stack exchange,提问作者Md. Al Amin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 07:53:11