Android Firebase通知部分设备未接收,Logcat报GCM相关错误
我在Android项目中集成Firebase通知功能后,整体运行正常,但部分设备无法接收通知。查看Logcat发现如下日志:
05-17 17:38:22.292 27292-27292/com.example.myapp D/ActivityThread: BDC-Calling onReceive: intent=Intent { act=com.google.android.c2dm.intent.RECEIVE flg=0x10 pkg=com.example.myapp cmp=com.example.myapp/com.google.firebase.iid.FirebaseInstanceIdReceiver@422443a8 }, ordered=true, receiver=com.google.firebase.iid.FirebaseInstanceIdReceiver@422443a8
05-17 17:38:22.295 27292-27292/com.example.myapp E/FirebaseInstanceId: Error resolving target intent service, skipping classname enforcement. Resolved service was: tv.peel.app/com.peel.receiver.FCMService
05-17 17:38:22.411 27292-27292/com.example.myapp D/ActivityThread: BDC-RECEIVER handled : 0 / ReceiverData{intent=Intent { act=com.google.android.c2dm.intent.RECEIVE flg=0x10 pkg=com.example.myapp (has extras) } packageName=com.example.myapp resultCode=-1 resultData=null resultExtras=null}
注:com.google.android.c2dm.intent.RECEIVE属于GCM相关,但我从未在应用中使用过GCM。
我使用PHP Curl通过Firebase发送数据负载,代码如下:
$fields = array ( 'registration_ids' => $registrationIds, 'data' => $data ); $headers = array ( 'Authorization: key=' . API_ACCESS_KEY, 'Content-Type: application/json' ); $ch = curl_init(); curl_setopt( $ch,CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send' ); curl_setopt( $ch,CURLOPT_POST, true ); curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers ); curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true ); curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, true ); curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $fields ) ); $result = curl_exec($ch ); curl_close( $ch ); echo $result;
返回结果显示发送成功:
{ "multicast_id": 5419052642417855073, "success": 1, "failure": 0, "canonical_ids": 0, "results": [ { "message_id": "0:1526567349119146%bc732c83f9fd7ecd" } ] }
Manifest中的服务配置如下:
<service android:name=".firebase.MyFirebaseMessagingService" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service> <service android:name=".firebase.MyFirebaseInstanceIDService" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.INSTANCE_ID_EVENT" /> </intent-filter> </service>
请问该如何解决部分设备无法接收Firebase通知的问题?
先看Logcat里的核心错误:Error resolving target intent service, skipping classname enforcement. Resolved service was: tv.peel.app/com.peel.receiver.FCMService——这说明你的设备上的Peel投屏应用(通常是系统预装)干扰了FCM的服务路由,系统错误地把FCM消息导向了Peel的服务,而非你自己应用的服务。结合你的配置,我整理了几个针对性的解决步骤:
1. 提升自定义FCM服务的优先级
在Manifest中给你的MyFirebaseMessagingService的intent-filter设置最高优先级,确保系统优先选择你的服务处理FCM消息:
<service android:name=".firebase.MyFirebaseMessagingService" android:exported="false"> <intent-filter android:priority="1000"> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service>
优先级范围是-1000到1000,设为1000能保证你的服务比其他同类型服务先被系统选中。
2. 补充FCM必要的权限配置
FCM基于C2DM演进,即便你没用到GCM,也需要确保Manifest中添加了核心权限:
<!-- 允许接收C2DM消息 --> <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> <!-- 自定义签名权限,防止其他应用伪造C2DM消息 --> <permission android:name="${applicationId}.permission.C2D_MESSAGE" android:protectionLevel="signature" /> <uses-permission android:name="${applicationId}.permission.C2D_MESSAGE" />
部分定制ROM会严格校验这些权限,缺失可能导致消息无法正常接收。
3. 正确处理消息类型
你当前发送的是纯data负载消息,这类消息不会自动在系统通知栏显示,必须在MyFirebaseMessagingService的onMessageReceived方法中手动创建通知:
@Override public void onMessageReceived(RemoteMessage remoteMessage) { // 从data中提取内容 String title = remoteMessage.getData().get("title"); String body = remoteMessage.getData().get("body"); // 创建并显示通知 NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "YOUR_CHANNEL_ID") .setSmallIcon(R.drawable.ic_notification) .setContentTitle(title) .setContentText(body) .setPriority(NotificationCompat.PRIORITY_DEFAULT); NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); notificationManager.notify(1, builder.build()); }
如果希望系统自动显示通知,可以在发送时同时包含notification字段:
$fields = array ( 'registration_ids' => $registrationIds, 'notification' => array( 'title' => '通知标题', 'body' => '通知内容' ), 'data' => $data );
注:应用在后台时,纯notification消息由系统托盘直接显示;应用在前台时,才会触发onMessageReceived。
4. 处理设备系统限制与冲突应用
- 针对Peel应用干扰的设备,可暂时禁用该应用测试是否恢复正常;面向用户时,可引导他们检查是否有类似系统应用劫持了FCM服务。
- 检查电池优化设置:小米、华为、OPPO等定制ROM的省电模式会杀死后台服务,需将你的应用加入“后台运行白名单”。
- 确认通知权限已开启:进入设备设置→应用→你的应用→通知,确保权限处于启用状态。
5. 升级Firebase SDK到最新版本
旧版本SDK可能存在与定制ROM的兼容性问题,建议在build.gradle中升级到最新稳定版:
// 项目级build.gradle classpath 'com.google.gms:google-services:4.4.0' // 替换为最新版本 // 模块级build.gradle implementation 'com.google.firebase:firebase-messaging:23.3.1' // 替换为最新版本
6. 调整服务的Exported属性
虽然官方建议MyFirebaseMessagingService设为exported="false",但部分定制ROM可能需要设为true才能正常接收消息,可尝试修改后测试:
<service android:name=".firebase.MyFirebaseMessagingService" android:exported="true"> <intent-filter android:priority="1000"> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service>
内容的提问来源于stack exchange,提问作者KhairAllah Najdawi

