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

如何获取已登录用户的Expo-Token以实现跨用户通知?

获取已登录用户的Expo Token并用于跨用户通知

核心思路

你需要把Expo Token和用户ID绑定,并将绑定关系存储到你的后端服务器——因为只有后端能在其他用户触发操作时,根据目标用户ID找到对应的Token,调用Expo的推送API发送通知。AsyncStorage仅用于本地维护登录状态,配合判断何时获取/同步Token。

具体步骤

1. 安装依赖

先确保安装Expo通知相关包:

npx expo install expo-notifications expo-device

2. 处理通知权限

必须先获取用户的通知授权,否则无法拿到Token。可以在登录成功后或App启动时请求:

import * as Notifications from 'expo-notifications';
import * as Device from 'expo-device';

async function requestNotificationPermissions() {
  if (!Device.isDevice) {
    alert('请在真实设备上测试通知功能');
    return false;
  }

  const { status: existingStatus } = await Notifications.getPermissionsAsync();
  let finalStatus = existingStatus;
  
  if (existingStatus !== 'granted') {
    const { status } = await Notifications.requestPermissionsAsync();
    finalStatus = status;
  }

  return finalStatus === 'granted';
}

3. 在登录成功后获取并同步Token

用户登录成功(你用AsyncStorage存储userInfo后),立即获取Token并上传到后端:

import AsyncStorage from '@react-native-async-storage/async-storage';

async function handleLoginSuccess(userInfo) {
  // 1. 存储登录状态到AsyncStorage
  await AsyncStorage.setItem('user', JSON.stringify(userInfo));

  // 2. 请求通知权限
  const hasPermission = await requestNotificationPermissions();
  if (!hasPermission) {
    alert('需要开启通知权限才能接收消息');
    return;
  }

  // 3. 获取Expo Token
  const expoToken = await Notifications.getExpoPushTokenAsync({
    projectId: '你的Expo项目ID', // 在app.json中可以找到
  });

  // 4. 将Token和用户ID绑定,上传到后端存储
  await fetch('你的后端接口地址/user/save-token', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      userId: userInfo.id,
      expoToken: expoToken.data,
    }),
  });
}

4. App启动时同步已登录用户的Token

如果用户之前已经登录(AsyncStorage中有userInfo),App启动时要检查Token是否有效,或者重新获取并同步:

// 在App.js的useEffect中执行
useEffect(() => {
  async function syncTokenOnAppStart() {
    const storedUser = await AsyncStorage.getItem('user');
    if (!storedUser) return; // 未登录,跳过

    const userInfo = JSON.parse(storedUser);
    const hasPermission = await requestNotificationPermissions();
    if (!hasPermission) return;

    const expoToken = await Notifications.getExpoPushTokenAsync({
      projectId: '你的Expo项目ID',
    });

    // 调用后端接口更新Token(避免Token过期或变更)
    await fetch('你的后端接口地址/user/update-token', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        userId: userInfo.id,
        expoToken: expoToken.data,
      }),
    });
  }

  syncTokenOnAppStart();
}, []);

5. 监听Token变化

Expo Token可能因设备重装、系统更新等原因变更,所以要监听变化并同步到后端:

useEffect(() => {
  const subscription = Notifications.addPushTokenListener(async ({ data: newToken }) => {
    const storedUser = await AsyncStorage.getItem('user');
    if (!storedUser) return;

    const userInfo = JSON.parse(storedUser);
    // 上传新Token到后端
    await fetch('你的后端接口地址/user/update-token', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        userId: userInfo.id,
        expoToken: newToken,
      }),
    });
  });

  return () => subscription.remove();
}, []);

6. 后端处理逻辑

你的后端需要维护一张用户-Token映射表,当其他用户执行操作时:

  1. 确定目标用户ID
  2. 从映射表中取出该用户的Expo Token
  3. 调用Expo的推送API发送通知(请求地址:https://exp.host/--/api/v2/push/send)

关键注意事项

  • 不要仅在本地存储Token:本地Token无法被后端获取,必须上传到服务器才能实现跨用户通知。
  • Token可能过期:定期同步或监听Token变化,确保后端存储的是有效Token。
  • 权限处理:始终先检查权限,没有权限时引导用户去设置开启。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 09:20:20