Expo50+React Native集成Stream.io与FCM,Android推送通知失效求助
Android 33 模拟器无法接收 FCM 推送排查方案(基于 Expo 50 + React Native + Stream.io)
问题背景
我开发了一款基于Expo 50 + React Native的应用,运行在Android 33系统上。使用Stream.io作为聊天基础设施,Firebase Cloud Messaging(FCM)实现推送通知。iOS端集成正常,但Android端(Pixel 7 Pro模拟器,Android 33)无法接收推送通知。
代码实现步骤:
- 通过
PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS)申请通知权限; - 调用Firebase的
messaging().getToken()获取设备令牌; - 通过以下代码将设备令牌存储到Stream.io:
client.setLocalDevice({ id: token, push_provider, push_provider_name, });
执行后无代码错误,发送消息时可见Stream.io已将消息发送至FCM。
排查步骤
1. 确认通知权限是否真正生效
Android 13(API 33)要求显式申请POST_NOTIFICATIONS权限,但模拟器可能存在弹窗不触发的情况:
- 手动进入模拟器「设置 > 应用 > 你的应用 > 通知」,确认通知权限已开启;
- 代码中增加权限结果校验,避免假成功:
const permissionStatus = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS); if (permissionStatus !== PermissionsAndroid.RESULTS.GRANTED) { console.log("通知权限未授予"); // 提示用户手动开启权限 }
2. 验证 Expo FCM 基础配置
Expo 50 集成FCM需确保配置无遗漏:
- 检查
app.json中android.googleServicesFile是否指向正确的google-services.json; - 确认
expo-notifications和expo-firebase-messaging依赖安装完成,执行expo prebuild --clean重新生成原生代码; - 用
messaging().getToken()返回的令牌,直接在Firebase控制台发送测试推送,验证模拟器能否接收(排除Stream.io环节问题)。
3. 检查模拟器推送接收环境
Pixel 7 Pro Android 33模拟器存在特定限制:
- 必须登录Google账号(FCM依赖Google服务框架,未登录可能无法接收推送);
- 关闭应用的电池优化:进入「设置 > 电池 > 电池优化」,将你的应用设为「不优化」;
- 尝试创建新的Android 33模拟器实例测试,避免旧模拟器缓存干扰。
4. 校验 Stream.io 设备配置参数
确认setLocalDevice参数符合要求:
push_provider必须设为'firebase';push_provider_name需匹配你的FCM项目配置,通常设为'fcm'或Firebase项目ID;- 登录Stream控制台,进入「应用 > 用户 > 目标用户 > 设备」,确认令牌已正确存储且参数无误。
5. 适配 Android 13 通知规范
Stream.io发送的FCM消息需适配Android 13要求:
- 确保消息包含
notification字段(纯data消息在Android 13后台处理逻辑不同); - 提前创建通知渠道,Expo要求Android 13通知必须绑定渠道:
import * as Notifications from 'expo-notifications'; async function createChatNotificationChannel() { await Notifications.setNotificationChannelAsync('chat', { name: '聊天通知', importance: Notifications.AndroidImportance.DEFAULT, sound: 'default', }); } // 应用启动时调用该函数
6. 检查通知监听逻辑
确认应用已正确处理FCM消息:
- 注册前台和后台消息监听:
import { messaging } from '@react-native-firebase/messaging'; messaging().onMessage(async remoteMessage => { console.log('前台收到消息:', remoteMessage); // 处理前台通知展示 }); messaging().setBackgroundMessageHandler(async remoteMessage => { console.log('后台收到消息:', remoteMessage); });
- 排查是否有第三方插件或自定义代码拦截了通知。
内容的提问来源于stack exchange,提问作者Felipe Peña
相关产品推荐
相关产品推荐

