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

React Native Expo iOS:设置中通知开关变更后如何获取推送令牌

解决Expo应用监听通知权限变更并同步推送令牌的方案

核心思路

要实现监听系统设置中通知权限的变更(无论APP处于前台、后台,还是用户修改后未返回APP),需结合expo-notifications的权限监听API,以及expo-app-state处理APP状态切换时的权限校验,覆盖所有场景下的令牌同步需求。

具体实现步骤

1. 实时监听权限变更

使用Notifications.addNotificationPermissionListener可以实时捕获权限状态变化,不管用户是在APP内还是系统设置中修改权限,该监听器都会触发:

import * as Notifications from 'expo-notifications';
import * as AppState from 'expo-app-state';

// 初始化权限监听器
const setupPermissionListener = async () => {
  // 先获取当前权限状态做初始校验
  const currentStatus = await Notifications.getPermissionsAsync();
  if (currentStatus.granted) {
    const token = await Notifications.getExpoPushTokenAsync();
    await saveTokenToDatabase(token.data); // 替换为你的数据库存储逻辑
  }

  // 添加权限变更监听
  const listener = Notifications.addNotificationPermissionListener(async (status) => {
    if (status.granted) {
      // 权限开启时获取令牌并存库
      const token = await Notifications.getExpoPushTokenAsync();
      await saveTokenToDatabase(token.data);
    } else {
      // 权限关闭时移除数据库中的令牌
      await removeTokenFromDatabase();
    }
  });

  return listener;
};

2. 处理APP激活时的权限校验

如果用户修改权限后直接返回APP,或APP从后台切回前台,通过AppState监听激活状态,确保每次APP启动/激活时都同步最新权限和令牌:

const setupAppStateListener = () => {
  const appStateListener = AppState.addEventListener('change', async (nextAppState) => {
    if (nextAppState === 'active') {
      // APP回到前台,校验当前权限状态
      const status = await Notifications.getPermissionsAsync();
      if (status.granted) {
        const token = await Notifications.getExpoPushTokenAsync();
        await saveTokenToDatabase(token.data);
      } else {
        await removeTokenFromDatabase();
      }
    }
  });

  return appStateListener;
};

3. 平台特殊配置与注意事项

  • iOS配置:需在app.json中添加权限描述,确保系统弹窗正常展示:
    {
      "expo": {
        "ios": {
          "infoPlist": {
            "NSUserNotificationUsageDescription": "用于接收实时消息通知",
            "NSAlertUsageDescription": "用于接收实时消息通知"
          }
        }
      }
    }
    
  • Android 13+适配:需单独请求POST_NOTIFICATIONS权限,可在APP启动时触发:
    await Notifications.requestPermissionsAsync({
      android: {
        postNotifications: true,
      },
    });
    
  • 清理监听器:组件卸载时移除监听器避免内存泄漏:
    useEffect(() => {
      const permissionListener = setupPermissionListener();
      const appStateListener = setupAppStateListener();
    
      return () => {
        permissionListener.remove();
        appStateListener.remove();
      };
    }, []);
    

用户未返回APP的场景处理

如果用户修改权限后完全未返回APP(APP处于后台/终止状态),无法直接触发代码执行,可通过以下方式覆盖:

  • 等用户下次打开APP时,利用AppState的active状态校验权限并同步令牌;
  • Android可结合expo-task-manager实现后台定期检查,但会增加电池消耗,需谨慎使用;
  • iOS后台任务限制严格,仅能依赖用户下次启动APP时同步。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 01:37:32