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

React Native中react-native-push-notification后台推送问题求助

解决React Native后台/未运行状态下推送通知接收与点击跳转问题

你已经搞定了前台接收通知的逻辑,接下来咱们把后台和未运行状态的推送问题也解决掉,同时确保点击通知能正常打开APP。结合你用的react-native-push-notification和Firebase云函数,我给你梳理几个关键调整点:

1. 先搞懂FCM的两种消息类型

FCM推送分通知消息和数据消息,不同APP状态下的处理逻辑完全不一样:

  • 通知消息:由FCM SDK直接展示,APP未运行时不会触发onNotification回调,只有用户点击通知才会启动APP并传递数据。
  • 数据消息:不管APP处于前台、后台还是未运行状态,都会把数据传递到onNotification,需要你自己处理通知展示逻辑。

你的Firebase payload同时包含了notification和data字段,这会导致后台/未运行时FCM优先处理notification字段,和你预期的逻辑冲突,咱们先调整payload格式。

2. 调整Firebase云函数的Payload

删掉notification字段,只用data字段(这样无论APP状态如何,数据都会传递到你的回调里),同时补全必要参数:

export const sendNotificationTest = functions.https.onRequest(async (req, res) => {
  try {
    const { token } = req.body;
    let targetToken = "coeC4T6tmeU:APA91bGEQs4MRQXq4C09SKpyK2Oxz7gIKS-QdoGGKeCcxQj2CXGpCD7qe763WnFVgQRer81iZGscASVq-QP7_I81xtCM9vfiPitQJ4P6HFSH3QiGQQljiLPBixsVcCtbDNCZX4z4u8n-"
    let payload = {
      data: {
        title: "Alarm",
        body: "First Alarm",
        subtitle: "First Alarm",
        color: "#00ACD4",
        priority: "high",
        icon: "ic_notif",
        show_in_foreground: 'true',
        channelId:'sqtrivia-channel',
        click_action: "OPEN_APP_ACTION" // 自定义action,后续Android配置要对应
      }
    };

    // 发送推送(补全你的发送逻辑)
    await admin.messaging().sendToDevice(targetToken, payload);
    res.status(200).send("Notification sent successfully");
  } catch (error) {
    console.error(error);
    res.status(500).send("Error sending notification");
  }
});

3. 优化react-native-push-notification配置

你的初始化逻辑有些冗余,咱们简化并调整关键配置:

修改initPushNotification方法

initPushNotification() {
  console.log('Initializing push notification')
  // 先创建Android通知渠道(8.0+必须)
  PushNotification.createChannel(
    {
      channelId: "sqtrivia-channel", // 和payload里的channelId保持一致
      channelName: "SQ Trivia Notifications",
      channelDescription: "Notifications for SQ Trivia app",
      soundName: "default",
      importance: 4,
      vibrate: true,
    },
    (created) => console.log(`Notification channel created: ${created}`)
  );

  PushNotification.configure({
    onRegister: function (token) {
      AppStore.setFCMToken(token.token)
      FirebaseService.setTokenData(token.token)
    },
    onNotification: function (notification) {
      console.log('Received notification data:', notification);
      
      // 统一处理通知展示:不管前台后台,都调用localNotification弹出
      if (notification.data) {
        const { title, body, subtitle, color, channelId } = notification.data;
        PushNotification.localNotification({
          id: '0',
          autoCancel: true,
          largeIcon: "ic_launcher",
          smallIcon: "ic_notification",
          bigText: body,
          subText: subtitle,
          color: color,
          vibrate: true,
          vibration: 300,
          // iOS专属配置
          title: title,
          message: body,
          playSound: false,
          // Android专属配置
          channelId: channelId,
          actions: '["Yes", "No"]',
        });
      }

      // 处理用户点击通知的逻辑:比如跳转到指定页面
      if (notification.userInteraction) {
        // 示例:navigation.navigate('NotificationDetail');
      }

      // iOS必须调用finish方法
      if (notification.finish) {
        notification.finish(PushNotificationIOS.FetchResult.NoData);
      }
    },
    senderID: "XXXXXXXXXX1",
    permissions: {
      alert: true,
      badge: true,
      sound: true
    },
    popInitialNotification: true, // 冷启动时自动处理初始通知
    requestPermissions: true,
  });
}

简化initEventPushNotification方法

原来的AppState监听里重复调用popInitialNotification没必要,因为配置里已经开启了自动处理,只保留必要的badge清零逻辑即可:

initEventPushNotification() {
  AppState.addEventListener('change', (state) => {
    console.log('App state changed:', state);
    if (state === 'background') {
      PushNotification.setApplicationIconBadgeNumber(0);
    }
  });
}

4. 平台专属配置(重中之重!)

Android配置

修改AndroidManifest.xml,确保点击通知能打开APP且不重复启动:

<activity
  android:name=".MainActivity"
  android:launchMode="singleTop" <!-- 关键:避免重复打开APP实例 -->
  ...>
  <intent-filter>
    <action android:name="OPEN_APP_ACTION" /> <!-- 和payload里的click_action一致 -->
    <category android:name="android.intent.category.DEFAULT" />
  </intent-filter>
</activity>

iOS配置

  1. 在Xcode中开启Capabilities里的Push Notifications。
  2. 开启Background Modes下的Remote notifications选项,确保后台能接收推送数据。

5. 测试要点

  • 后台测试:把APP退到后台,发送推送,检查通知是否展示,点击是否能打开APP。
  • 冷启动测试:完全杀死APP,发送推送,检查通知是否弹出,点击是否能启动APP并触发onNotification。
  • 日志排查:用adb logcat(Android)或Xcode控制台(iOS)查看推送相关日志,定位可能的错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:24:55