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

React-Native Firebase Cloud Messaging:点击通知唤醒无事件求助

解决React Native FCM后台唤醒时无法捕获通知数据的问题

我之前也碰到过一模一样的问题,核心原因是你在页面组件的componentDidMount里注册FCM通知监听太晚了——当点击通知把App从后台(或杀死状态)唤醒时,通知事件在App启动初期就已经触发了,等你的News_Screen挂载完成、监听注册好的时候,事件早就过去了。下面是具体的解决步骤:

1. 把FCM监听移到App根组件,提前注册

你需要在App启动的最早期(比如app/index.js这个根组件里)就完成FCM的初始化和监听注册,而不是等到页面挂载。这样无论App是前台运行、后台唤醒还是冷启动,监听都能及时捕获事件。

根组件示例代码

import React, { Component } from 'react';
import { Platform } from 'react-native';
import FCM, { FCMEvent } from 'react-native-fcm';
import { NavigationContainer } from '@react-navigation/native';
import StackNavigator from './your-path-to/StackNavigator';

class App extends Component {
  navigationRef = null;

  componentDidMount() {
    // 关键:获取App冷启动/后台唤醒时的初始通知数据
    FCM.getInitialNotification().then(notif => {
      if (notif && notif.opened_from_tray) {
        console.log('初始通知数据:', notif);
        // 处理页面跳转
        if (notif.data?.screen) {
          this.navigationRef.navigate(notif.data.screen);
        }
      }
    });

    // 监听常规通知事件(前台/后台唤醒的热启动场景)
    this.notificationListener = FCM.on(FCMEvent.Notification, notif => {
      console.log('收到通知:', notif);
      if (notif.opened_from_tray && notif.data?.screen) {
        this.navigationRef.navigate(notif.data.screen);
      }
    });

    // 权限请求、Token获取可以统一放在这里
    FCM.requestPermissions({ badge: false, sound: true, alert: true })
      .catch(e => console.error('FCM权限请求失败:', e));
    
    FCM.getFCMToken().then(token => {
      console.log('FCM Token:', token);
      // 把Token上传到你的服务器
    });

    if (Platform.OS === 'ios') {
      FCM.getAPNSToken().then(token => console.log('APNS Token:', token));
    }

    // 监听Token刷新
    this.refreshTokenListener = FCM.on(FCMEvent.RefreshToken, token => {
      console.log('Token刷新:', token);
      // 更新服务器上的Token
    });
  }

  componentWillUnmount() {
    // 移除监听,避免内存泄漏
    this.notificationListener?.remove();
    this.refreshTokenListener?.remove();
  }

  render() {
    return (
      <NavigationContainer ref={ref => this.navigationRef = ref}>
        <StackNavigator />
      </NavigationContainer>
    );
  }
}

export default App;

2. 配置AndroidManifest(仅Android平台)

Android系统需要明确的click_action配置,才能把通知点击事件正确传递给App。

打开android/app/src/main/AndroidManifest.xml,在你的MainActivity的<intent-filter>里添加以下内容:

<intent-filter>
  <!-- 保留你原有的action和category,比如下面这两行 -->
  <action android:name="android.intent.action.MAIN" />
  <category android:name="android.intent.category.LAUNCHER" />
  
  <!-- 添加这两行 -->
  <action android:name="OPEN_ACTIVITY_1" />
  <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

然后在你发送FCM通知的payload里,必须在data字段中包含click_action,值要和上面配置的一致:

{
  "to": "你的设备FCM Token",
  "notification": {
    "title": "测试通知",
    "body": "点击跳转页面"
  },
  "data": {
    "screen": "Menu_Screen",
    "click_action": "OPEN_ACTIVITY_1" // 和AndroidManifest里的action名称一致
  }
}

3. 为什么之前的代码不行?

你之前把监听放在News_Screen的componentDidMount里,当App从后台被通知唤醒时:

  1. App先启动,加载根组件
  2. 然后加载News_Screen,执行componentDidMount注册监听
  3. 但通知事件在App启动的第一步就已经触发了,此时监听还没注册,所以完全捕获不到

而FCM.getInitialNotification()就是专门用来解决这个问题的——它会返回App冷启动或后台唤醒时触发的那个初始通知数据,不管监听注册时间早晚,只要在App启动后调用就能拿到。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:04:47