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

React Native Firebase消息:后台/杀死状态下处理通知与角标更新

解决React Native Firebase Messaging后台/杀死状态下的通知处理问题

针对你使用@react-native-firebase/messaging@7.8.4遇到的两个问题,我会一步步给出具体的解决方案:


1. 收到通知横幅时立即唤醒应用执行处理逻辑

你推测的原因完全正确:Payload中缺少content-available: 1(iOS aps字段)会导致应用无法在后台/杀死状态下被唤醒,setBackgroundMessageHandler自然不会触发。要实现后台静默处理,需要同时满足后端配置、iOS原生配置和RN代码设置三个条件:

步骤1:修改后端推送Payload

必须在iOS的aps字段中添加content-available: 1,同时确保FCM推送的优先级设为high(iOS要求高优先级才能触发后台唤醒)。调整后的Payload示例:

{
  "aps": {
    "alert": {
      "body": "msg",
      "title": "iOS"
    },
    "sound": "default",
    "content-available": 1, // 核心:开启后台唤醒
    "mutable-content": 1 // 处理富媒体时可选,非必须
  },
  "deeplink": "myapp://profile",
  "mediaType": "image",
  "notificationid": "maskedData"
}

注意:如果通过FCM API发送,要在请求体中设置priority: "high",否则iOS可能会延迟或忽略后台唤醒请求。

步骤2:配置iOS原生项目的Background Modes

打开Xcode,进入你的项目target:

  • 切换到Signing & Capabilities标签
  • 点击+ Capability,添加Background Modes
  • 勾选Remote notifications选项

这一步是iOS允许应用在后台接收远程通知并唤醒的必要配置,缺一不可。

步骤3:正确注册setBackgroundMessageHandler

在@react-native-firebase/messaging@7.x版本中,setBackgroundMessageHandler必须在App组件挂载之前注册(比如在index.js的最顶部),否则无法在杀死状态下触发。示例代码:

// index.js
import { AppRegistry } from 'react-native';
import messaging from '@react-native-firebase/messaging';
import App from './App';
import AsyncStorage from '@react-native-async-storage/async-storage';

// 后台消息处理函数,必须在App注册前定义
messaging().setBackgroundMessageHandler(async remoteMessage => {
  console.log('后台收到通知,开始处理:', remoteMessage);
  
  // 示例:将通知存储到本地(可根据notificationid去重)
  try {
    const storedNotifications = await AsyncStorage.getItem('app_notifications') || '[]';
    const notifications = JSON.parse(storedNotifications);
    const isDuplicate = notifications.some(n => n.data.notificationid === remoteMessage.data.notificationid);
    if (!isDuplicate) {
      notifications.push(remoteMessage);
      await AsyncStorage.setItem('app_notifications', JSON.stringify(notifications));
    }
  } catch (error) {
    console.error('存储通知失败:', error);
  }
});

AppRegistry.registerComponent('YourAppName', () => App);

这样,当通知到达时,即使应用在后台或被杀死,系统也会短暂唤醒应用执行这个handler,你就可以在其中完成存储通知等逻辑。


2. 后台/杀死状态下更新应用角标数字

角标更新有两种实现方式,根据你的需求选择:

方式1:后端直接指定角标数字(最简单)

如果角标数字可以由后端计算好,直接在Payload的aps字段中添加badge值即可,iOS会自动更新角标,不需要应用唤醒:

{
  "aps": {
    // ...其他字段
    "badge": 3 // 直接设置角标数字,设为0可清除角标
  }
}

方式2:前端动态计算角标(需要后台唤醒)

如果需要基于本地存储的通知数量动态更新角标,就需要在setBackgroundMessageHandler中调用messaging().setBadgeNumber()方法,前提是已经完成了上面第一个问题的所有配置(确保handler能被触发)。示例代码:

// 在setBackgroundMessageHandler中添加角标更新逻辑
messaging().setBackgroundMessageHandler(async remoteMessage => {
  // ...存储通知的逻辑
  
  // 计算当前通知数量并更新角标
  const storedNotifications = await AsyncStorage.getItem('app_notifications') || '[]';
  const notificationsCount = JSON.parse(storedNotifications).length;
  await messaging().setBadgeNumber(notificationsCount);
});

注意:iOS系统对后台唤醒的时间有限制,所以这个逻辑要尽量简洁,避免耗时操作,否则系统会终止进程导致角标更新失败。


额外注意事项

  • 确保用户已经授予应用通知权限(只需“允许通知”,不需要额外后台权限,只要开启了Background Modes的Remote notifications即可)。
  • 在@react-native-firebase/messaging@7.x中,setBackgroundMessageHandler的回调函数必须是异步的,且要尽量快速完成。
  • 测试杀死状态下的后台处理时,不要用Xcode调试(Xcode附加调试会让应用处于特殊状态),应该直接在真机上卸载重装后测试。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 09:22:50