同一Firebase账号下两个Android应用FCM消息接收失败及Token存储疑问
问题解答
一、你的逻辑是否正确?
同Firebase账号下的两个Android应用完全可以互相发送FCM消息,但当前接收方收不到消息,说明流程存在细节疏漏,核心逻辑方向没问题,但具体实现有错误,常见原因包括:
- 存储的FCM Token已失效:FCM Token会在应用卸载重装、设备系统更新、应用签名变更等场景下刷新,若存的是旧Token,发送时会显示“成功”但实际无法送达。
- 接收方应用的FCM配置异常:比如
google-services.json文件未正确对应目标项目,或者依赖的Firebase SDK版本不兼容。 - 消息格式不符合要求:如果发送的是通知消息,接收方应用在后台时会由系统托盘处理,但应用被强制停止可能收不到;如果是数据消息,必须在
FirebaseMessagingService的onMessageReceived方法中手动处理,否则不会触发回调。 - 接收方的
FirebaseMessagingService未正确注册:Manifest中未声明该服务,或者服务类的包名、权限配置错误。 - 设备限制:接收设备的通知权限未开启,或者应用被系统列入后台耗电限制名单,导致FCM服务无法正常运行。
二、SharedPreference存储FCM Token用于发送是否可行?
临时测试场景可行,但正式生产环境完全不推荐:
- 可行的点:如果手动获取接收方的有效Token,存入发送方的SharedPreference后直接调用FCM接口发送,只要Token有效就能成功(但你当前的问题大概率是Token无效或接收方配置问题)。
- 不可行的核心原因:
- Token会动态刷新:FCM Token并非永久有效,Firebase会定期更新Token,存的SP中的Token很快会失效,无法保证长期可用。
- 跨应用无法共享SP:两个应用的SharedPreference是隔离的,只能手动将接收方的Token复制到发送方的SP中,无法自动同步,完全不适合实际业务场景。
三、正确的操作方式
1. Token的统一存储与同步
使用Firebase提供的Realtime Database或Cloud Firestore来存储设备Token:
- 每个应用启动时(或在
FirebaseMessagingService的onNewToken方法中),将自身的最新Token上传到数据库,同时关联设备标识(比如用户ID、设备UUID)。 - 发送方需要发送消息时,从数据库中查询目标设备的最新Token,再调用FCM接口发送。
示例代码(上传Token到Firestore):
// 在FirebaseMessagingService的onNewToken方法中更新Token override fun onNewToken(token: String) { super.onNewToken(token) // 假设用户已登录,用用户ID作为文档ID val db = FirebaseFirestore.getInstance() db.collection("device_tokens") .document(currentUserId) .set(mapOf("token" to token, "app_id" to BuildConfig.APPLICATION_ID)) .addOnSuccessListener { /* 更新成功 */ } }
2. 发送消息的正确姿势
确保发送的消息格式符合接收方的处理逻辑:
- 如果需要前台/后台都能触发自定义逻辑,发送数据消息,示例请求体:
{ "to": "目标设备Token", "data": { "title": "测试消息", "content": "这是来自另一个应用的消息", "type": "cross_app" } }
- 接收方在
FirebaseMessagingService中处理:
override fun onMessageReceived(remoteMessage: RemoteMessage) { super.onMessageReceived(remoteMessage) remoteMessage.data?.let { data -> // 处理数据消息,比如弹出自定义通知 val title = data["title"] val content = data["content"] showCustomNotification(title, content) } }
3. 排查接收问题的步骤
- 用Firebase控制台的测试消息功能,直接输入接收方的Token发送消息,确认是否能收到,排除Token有效性问题。
- 检查接收方的
google-services.json是否与Firebase控制台中对应应用的配置一致,包名是否匹配。 - 确认Manifest中已正确注册
FirebaseMessagingService:
<service android:name=".MyFirebaseMessagingService" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service>
- 检查设备的通知权限是否开启,应用是否被允许后台运行。
内容的提问来源于stack exchange,提问作者Md Shadab
相关产品推荐
相关产品推荐

