RN中如何处理推送通知(本地推送、远程推送),点击推送跳转指定页面?

0 阅读2分钟

在 React Native(RN)中处理推送通知,一般分为三块:

1️⃣ 本地推送(Local Notification)
2️⃣ 远程推送(Push Notification / FCM / APNs)
3️⃣ 点击通知跳转页面(Deep Link / Navigation)

我给你按“工程实战”的方式讲,直接能落地。


一、常用方案选型

目前主流有两套:

✅ 方案1(推荐)

  • Firebase(FCM 推送)
  • react-native-firebase
  • Notifee(处理本地通知 + 点击事件)

👉 优点:稳定、功能全、可控性强(企业项目首选)


方案2(简单但旧)

  • react-native-push-notification

👉 不太推荐(维护一般)


二、基础架构(你要理解)

推送流程:

服务端 -> FCM/APNs -> 手机 -> RN App -> 展示通知 -> 用户点击 -> 跳转页面

关键点:

  • 后台推送数据(data payload)
  • App 收到后展示通知
  • 点击通知时解析数据并导航

三、安装依赖(推荐方案)

yarn add @react-native-firebase/app
yarn add @react-native-firebase/messaging
yarn add @notifee/react-native

四、远程推送(FCM)

1️⃣ 请求权限

import messaging from '@react-native-firebase/messaging';

async function requestPermission() {
  const authStatus = await messaging().requestPermission();
  const enabled =
    authStatus === messaging.AuthorizationStatus.AUTHORIZED ||
    authStatus === messaging.AuthorizationStatus.PROVISIONAL;

  if (enabled) {
    console.log('授权成功');
  }
}

2️⃣ 获取 token(发给后端)

const token = await messaging().getToken();
console.log('FCM Token:', token);

3️⃣ 前台接收消息

messaging().onMessage(async remoteMessage => {
  console.log('前台收到消息:', remoteMessage);

  // 用 Notifee 展示本地通知
});

4️⃣ 后台/关闭状态处理

messaging().setBackgroundMessageHandler(async remoteMessage => {
  console.log('后台消息:', remoteMessage);
});

五、本地通知(Notifee)

1️⃣ 创建通知

import notifee from '@notifee/react-native';

async function displayNotification(data) {
  await notifee.displayNotification({
    title: data.title,
    body: data.body,
    android: {
      channelId: 'default',
    },
    data: data, // 关键:携带跳转参数
  });
}

2️⃣ 创建 channel(Android 必须)

await notifee.createChannel({
  id: 'default',
  name: 'Default Channel',
});

六、点击通知跳转页面(重点)

这是你最关心的 👇

核心思路

👉 推送数据里带上跳转信息

例如服务端 payload:

{
  "data": {
    "type": "order",
    "orderId": "123"
  }
}

1️⃣ App 已打开(前台点击)

notifee.onForegroundEvent(({ type, detail }) => {
  if (type === EventType.PRESS) {
    const data = detail.notification?.data;

    handleNavigation(data);
  }
});

2️⃣ App 在后台(点击通知)

notifee.onBackgroundEvent(async ({ type, detail }) => {
  if (type === EventType.PRESS) {
    const data = detail.notification?.data;

    handleNavigation(data);
  }
});

3️⃣ App 被杀死(冷启动)

const initialNotification = await notifee.getInitialNotification();

if (initialNotification) {
  const data = initialNotification.notification?.data;
  handleNavigation(data);
}

七、封装跳转逻辑(React Navigation)

import { navigationRef } from './navigationRef';

function handleNavigation(data) {
  if (!data) return;

  switch (data.type) {
    case 'order':
      navigationRef.navigate('OrderDetail', {
        id: data.orderId,
      });
      break;

    case 'message':
      navigationRef.navigate('MessagePage');
      break;
  }
}

八、navigationRef(关键)

因为推送是在“组件外触发”的:

import { createNavigationContainerRef } from '@react-navigation/native';

export const navigationRef = createNavigationContainerRef();
<NavigationContainer ref={navigationRef}>
  {/* routes */}
</NavigationContainer>

九、完整流程总结

  1. App 启动 → 请求权限
  2. 获取 FCM token → 给后端
  3. 后端发送 push(带 data)
  4. App 收到 → 用 Notifee 展示
  5. 用户点击 → 解析 data
  6. navigationRef 跳转页面

十、常见坑(很重要)

⚠️ iOS 不显示通知
→ 没开权限 / 没配置 APNs

⚠️ Android 收不到
→ channel 没创建

⚠️ 点击没跳转
→ data 没传 or 没监听

⚠️ 冷启动跳转失败
→ 没用 getInitialNotification


十一、进阶建议(你这个级别可以做)

你有前端 7 年经验,可以直接做一层封装:

👉 NotificationService

  • 统一处理:

    • 权限
    • token
    • 收消息
    • 跳转

👉 Router Map:

const ROUTE_MAP = {
  order: 'OrderDetail',
  message: 'MessagePage',
};