如何获取已登录用户的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映射表,当其他用户执行操作时:
- 确定目标用户ID
- 从映射表中取出该用户的Expo Token
- 调用Expo的推送API发送通知(请求地址:
https://exp.host/--/api/v2/push/send)
关键注意事项
- 不要仅在本地存储Token:本地Token无法被后端获取,必须上传到服务器才能实现跨用户通知。
- Token可能过期:定期同步或监听Token变化,确保后端存储的是有效Token。
- 权限处理:始终先检查权限,没有权限时引导用户去设置开启。
内容的提问来源于stack exchange,提问作者Itay Lador
相关产品推荐
相关产品推荐

