Expo Notifications生产构建无法获取推送Token问题求助
Expo Notifications + Firebase Messaging生产环境无法获取推送Token问题排查
问题描述
我搭建了一个测试Expo Notifications与Firebase Messaging的应用,已完成以下配置:
- 正确引入Firebase提供的
google-services.json文件 - 在
app.json中添加权限:
"permissions": [ "POST_NOTIFICATIONS", "RECEIVE_BOOT_COMPLETED" ],
- 编写了通知权限请求与注册代码(见下方核心代码)
本地测试时推送功能完全正常,但发布生产构建后,应用不再显示Expo推送Token和设备Token。
核心代码
export default function App() { const [forceReload, setForceReload] = useState(true); const [notificationExpoToken, setNotificationExpoToken] = useState(''); const [notificationDeviceToken, setNotificationDeviceToken] = useState(''); const registerForPushNotificationsAsync = async () => { let tokenExpo; let tokenDevice; if (Platform.OS === 'android') { await Notifications.setNotificationChannelAsync('default', { name: 'default', importance: Notifications.AndroidImportance.MAX, vibrationPattern: [0, 250, 250, 250], lightColor: '#FF231F7C', }); } if (Device.isDevice) { const { status: existingStatus } = await Notifications.getPermissionsAsync(); let finalStatus = existingStatus; if (existingStatus !== 'granted') { const { status } = await Notifications.requestPermissionsAsync(); finalStatus = status; } if (finalStatus !== 'granted') { Alert.alert('ERROR', 'Non è stato possibile ricuperare il token per le notifiche!'); return; } tokenExpo = (await Notifications.getExpoPushTokenAsync()).data; setNotificationExpoToken(tokenExpo); tokenDevice = (await Notifications.getDevicePushTokenAsync()).data; setNotificationDeviceToken(tokenDevice); } else { Alert.alert('ERROR', 'Deve utilizzare un device per le notifiche push!'); } return tokenExpo; }; useEffect(()=>{ (async ()=>{ await registerForPushNotificationsAsync(); })(); }, [notificationExpoToken, notificationDeviceToken]); return ( <View style={styles.container} key={forceReload}> <StatusBar style="auto" /> <Text style={{fontWeight: 'bold', color: 'orange', marginVertical: 10}}>notificationExpoToken:</Text> <Text selectable style={{margin: 10}}>{notificationExpoToken}</Text> <Text style={{fontWeight: 'bold', color: 'blue', marginVertical: 10}}>notificationDeviceToken:</Text> <Text selectable style={{margin: 10}}>{notificationDeviceToken}</Text> <Button title={"Reload"} onPress={()=>{ setForceReload(!forceReload) }} /> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center', }, });
排查与解决方案
1. 核对Firebase生产环境配置
- 确认
google-services.json是生产环境专属配置文件,Firebase控制台中开发/生产环境的配置文件不通用,混用会导致生产构建无法正常获取Token。 - 检查
app.json中android.googleServicesFile的路径是否指向正确的生产环境文件,确保构建时该文件被正确打包。
2. 配置Expo生产环境推送凭证
- Expo Push Token:生产环境中
getExpoPushTokenAsync()需要关联Expo项目的生产级FCM凭证:- 进入Expo Dashboard的项目设置 -> 云消息服务(Push Notifications)
- 上传从Firebase控制台(项目设置 -> 云消息服务)获取的生产环境FCM服务器密钥
- 设备Token:若
google-services.json配置错误,getDevicePushTokenAsync()会直接失败,需确保文件的包名、API密钥等信息与生产构建一致。
3. 修复useEffect依赖循环问题
你的useEffect依赖了notificationExpoToken和notificationDeviceToken,会导致Token更新时重复调用注册函数,形成无限循环,最终引发Token获取异常。修改依赖数组为空,确保仅在组件挂载时执行一次:
useEffect(()=>{ (async ()=>{ await registerForPushNotificationsAsync(); })(); }, []); // 移除token依赖,仅在组件挂载时执行
4. 添加错误捕获与日志
生产环境无法直接查看调试信息,建议在Token获取逻辑中添加错误捕获,便于定位问题:
const registerForPushNotificationsAsync = async () => { try { // 原有逻辑... } catch (error) { console.error('Token获取失败:', error); Alert.alert('ERROR', `Token获取失败: ${error.message}`); } };
可使用Expo的Logcat工具(针对Android)查看生产构建的日志,定位具体错误。
5. 确认生产构建权限配置
- 对于Android 13+,
POST_NOTIFICATIONS需运行时请求,你的代码已处理,但需确认生产构建中该权限未被ProGuard/R8规则移除,app.json的android.permissions中需明确声明。 - 若使用EAS Build,检查
eas.json是否有覆盖权限的配置,确保生产构建包含所需权限。
6. 验证EAS Build配置(若使用EAS)
- 在
eas.json的生产构建配置中,确认android.googleServicesFile路径指向正确的生产环境文件:
{ "build": { "production": { "android": { "googleServicesFile": "./google-services-production.json" } } } }
- 查看构建日志,确认
google-services.json已被正确加载,无文件找不到或解析错误。
内容的提问来源于stack exchange,提问作者vcorrea
相关产品推荐
相关产品推荐

