Expo Android生产环境推送通知失效问题求助
问题详情
环境信息
- Expo SDK版本:40
- 平台:Android
- 状态:已eject,使用
gradlew assembleRelease打包并发布至Play商店,已配置FCM
核心问题
- 推送通知仅在本人开发设备的开发模式下正常:
- 其他设备的开发模式(USB执行
yarn react-native run-android)无法接收推送 - 生产环境(Play商店发布版本)也无法接收推送
- 其他设备的开发模式(USB执行
- 使用Insomnia调用
exp.host/--/api/v2/push/send接口测试,仅本人开发设备能收到,其他设备及生产环境均无响应 - 已确认所有设备安装应用后均生成了Exponent推送令牌,且重新安装后刷新了新令牌
- 当前使用
experienceId: @username/slug而非ApplicationId注册推送令牌
疑问点
- 能否在谷歌控制台或Expo控制台设置生产模式?具体位置在哪里?
- 仅本人开发设备能接收推送的原因是什么?
- 是否因使用
gradlew assembleRelease打包导致问题?是否需要改用eas build --platform android?
已尝试代码
// Notifications.setNotificationHandler(null); //也曾尝试此写法 Notifications.setNotificationHandler({ handleNotification: async () => { return { shouldShowAlert: true, shouldPlaySound: true, shouldSetBadge: false, }; }, });
解决方案
1. 推送环境配置(开发/生产模式区分)
Expo控制台设置
已eject的裸项目需在Expo控制台完成以下配置:
- 进入对应项目页面的**"Credentials"**板块
- 确认Android平台的FCM密钥分别配置了**开发(Debug)和生产(Release)**版本:开发模式用调试FCM密钥,生产模式需上传谷歌控制台下载的正式FCM服务账号密钥
- 确保
app.json中android.package字段与Play商店的ApplicationId完全一致,推送令牌注册必须绑定正确的ApplicationId,而非experienceId
谷歌控制台设置
- 进入谷歌云控制台对应项目的**"Firebase Cloud Messaging"**模块
- 打开**"项目设置" > "应用" > 对应Android应用**,在"签名证书指纹"栏添加Release包的SHA-1/SHA-256指纹:生产环境推送依赖签名指纹匹配,否则FCM会拒绝请求
2. 仅单设备能接收推送的原因
- 本人开发设备的推送令牌绑定了开发环境的experienceId,其他设备开发模式下可能因环境变量配置错误,令牌未正确关联FCM调试密钥
- 检查其他设备开发模式的日志,确认令牌生成时是否有错误,或是否成功关联FCM令牌
- 调用
exp.host接口时,需确保请求体包含目标设备的Exponent令牌、Android 8.0+必需的channelId,以及完整的title和body字段
3. 打包方式的问题
gradlew assembleRelease本身可用,但需确保打包配置正确:- 检查
android/app/build.gradle的buildTypes.release配置,若开启minifyEnabled或proguard,需添加Expo推送相关的混淆规则,避免推送代码被混淆 - 打包必须使用正式签名证书,而非调试证书,生产环境推送要求应用签名与谷歌控制台配置一致
- 检查
- 若之前用Expo Managed Workflow,切换到裸项目后建议用
eas build --platform android生成生产包,它会自动处理FCM密钥和签名证书的关联,减少手动配置错误
4. 推送令牌注册的关键修正
- 停止使用
experienceId注册令牌,改用app.json中android.package对应的ApplicationId - 代码中确保初始化时绑定正确参数:
import * as Notifications from 'expo-notifications'; await Notifications.setNotificationHandler({ handleNotification: async () => ({ shouldShowAlert: true, shouldPlaySound: true, shouldSetBadge: false, }), }); const token = await Notifications.getExpoPushTokenAsync({ projectId: '你的Expo项目ID', android: { channelId: '你的通知渠道ID', }, }); - Expo SDK40中,
getExpoPushTokenAsync需正确关联项目ID和包名,否则生成的令牌无法映射到FCM生产环境
内容的提问来源于stack exchange,提问作者Thomas Reolon
相关产品推荐
相关产品推荐

