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

React Native集成Firebase Cloud Messaging如何不点击通知获取数据

解决方案

你目前实现的逻辑仅覆盖了「点击通知唤起应用」的消息处理场景,对于用户忽略通知直接打开应用的情况,需要新增本地持久化存储通知+应用前台激活时拉取未读消息的逻辑,具体实现如下:


核心实现步骤

  • 收到推送消息时,无论用户是否点击通知,都先将完整消息存入本地持久化存储(可使用 AsyncStorage、MMKV 等本地存储方案),同时标记未读状态
  • 监听应用激活状态:包括应用冷启动完成、应用从后台切回前台两个时机,触发后读取本地所有未读通知统一处理
  • 消息被用户查看后,更新本地存储的消息状态为已读,避免重复处理

修改后的代码示例

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

// 存储通知到本地的通用方法
const saveNotificationToLocal = async (remoteMessage) => {
  // 生成消息唯一标识,也可以用推送服务返回的messageId
  const msgId = remoteMessage.messageId || Date.now().toString();
  const existingMsgs = await AsyncStorage.getItem('unreadNotifications');
  const msgList = existingMsgs ? JSON.parse(existingMsgs) : [];
  // 避免重复存储同一条消息
  if (!msgList.find(item => item.messageId === msgId)) {
    msgList.push({
      ...remoteMessage,
      isRead: false,
      saveTime: Date.now()
    });
    await AsyncStorage.setItem('unreadNotifications', JSON.stringify(msgList));
  }
}

// 处理本地未读通知的通用方法
const handleLocalUnreadMsgs = async () => {
  const existingMsgs = await AsyncStorage.getItem('unreadNotifications');
  const msgList = existingMsgs ? JSON.parse(existingMsgs) : [];
  const unreadMsgs = msgList.filter(item => !item.isRead);
  if (unreadMsgs.length > 0) {
    // 批量处理所有未读消息
    unreadMsgs.forEach(msg => handlerMessage(msg));
    // 可选:如果需要跳转可以在这里判断,或者统一展示消息列表
    // setInitialRoute('Messenger')
    
    // 处理后标记为已读,也可以根据业务需求在用户点击查看后再标记
    const updatedMsgs = msgList.map(item => ({...item, isRead: true}));
    await AsyncStorage.setItem('unreadNotifications', JSON.stringify(updatedMsgs));
  }
}

useEffect(() => {
    // 应用启动时先处理本地未读消息
    handleLocalUnreadMsgs();

    // 监听应用前后台切换
    const appStateListener = AppState.addEventListener('change', nextAppState => {
      if (nextAppState === 'active') {
        // 应用切回前台时处理未读消息
        handleLocalUnreadMsgs();
      }
    });

    messaging().setBackgroundMessageHandler(async remoteMessage => {
        // 后台收到消息先存本地
        await saveNotificationToLocal(remoteMessage);
        handlerMessage(remoteMessage)
        setInitialRoute('Messenger')
    });
    messaging().onMessage(async remoteMessage => {
        // 前台收到消息先存本地
        await saveNotificationToLocal(remoteMessage);
        handlerMessage(remoteMessage);
    });

    messaging()
        .getInitialNotification()
        .then(remoteMessage => {
            if (remoteMessage) {
                handlerMessage(remoteMessage);
                setInitialRoute('Messenger')
            }
        });

    // 卸载时移除监听
    return () => {
      appStateListener.remove();
    }
}, []);

补充说明:如果你的推送服务端支持未读消息拉取接口,也可以在应用激活时调用接口拉取用户所有未读消息,和本地存储方案搭配使用可靠性更高。

内容的提问来源于stack exchange,提问作者Darya Leushkina

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 21:15:04