Android端Firebase推送通知接收失败问题排查求助
排查Firebase云消息通知接收失败问题
以下是针对你当前配置的排查要点及修复建议:
1. 验证AndroidManifest中MessagingService的声明
确保MyFirebaseMessagingService的服务声明包含正确的intent-filter,否则无法接收Firebase消息事件:
<service android:name=".MyFirebaseMessagingService" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service>
注意android:name要与你的包名(com.example.sfawebview)和类名完全匹配。
2. 确认前台通知权限的动态申请逻辑
Android 13+(API 33)需要动态申请POST_NOTIFICATIONS权限,确保MainActivity中的权限申请代码完整:
import android.Manifest import android.content.pm.PackageManager import android.os.Build import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat private fun requestNotificationPermission() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions( this, arrayOf(Manifest.permission.POST_NOTIFICATIONS), 101 // 请求码可自定义 ) } } }
在onCreate方法中调用该函数,并在onRequestPermissionsResult中处理权限授予结果。
3. 适配PendingIntent的Flags(Android 12+)
你的代码中使用了PendingIntent.FLAG_ONE_SHOT,但Android 12+要求必须指定FLAG_IMMUTABLE或FLAG_MUTABLE,否则会导致通知无法创建。修改代码如下:
// 替换原PendingIntent创建代码 val pendingIntentFlags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE } else { PendingIntent.FLAG_ONE_SHOT } val pendingIntent = PendingIntent.getActivity( this, 0, intent, pendingIntentFlags )
同时移除@SuppressLint("UnspecifiedImmutableFlag")注解。
4. 提前创建通知渠道(Android 8+)
当前你在收到消息时才创建通知渠道,可能导致首次消息无法正常展示。建议在App启动时提前创建渠道:
- 创建自定义Application类:
package com.example.sfawebview import android.app.NotificationChannel import android.app.NotificationManager import android.os.Build import android.app.Application class MyApp : Application() { override fun onCreate() { super.onCreate() createNotificationChannel() } private fun createNotificationChannel() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val channel = NotificationChannel( channelId, // 与你定义的channelId一致 "Sweat Free", NotificationManager.IMPORTANCE_HIGH ).apply { description = "Sweat Free App通知渠道" } val notificationManager = getSystemService(NotificationManager::class.java) notificationManager.createNotificationChannel(channel) } } }
- 在AndroidManifest中声明该Application:
<application android:name=".MyApp" <!-- 其他原有配置 --> > <!-- 其他组件声明 --> </application>
5. 区分消息类型并适配后台处理
Firebase消息分为通知消息和数据消息:
- 如果发送的是通知消息(payload包含
notification字段):App后台时由系统自动展示通知,前台时才会触发onMessageReceived; - 如果发送的是数据消息(payload仅含
data字段):无论前台/后台,都需要你在onMessageReceived中手动处理通知展示。
当前你的代码仅处理了remoteMessage.notification不为空的情况,若发送的是纯数据消息,需补充处理逻辑:
override fun onMessageReceived(remoteMessage: RemoteMessage) { // 处理通知消息 remoteMessage.notification?.let { showNotification(it.title ?: "", it.body ?: "") } // 处理数据消息 if (remoteMessage.data.isNotEmpty()) { val title = remoteMessage.data["title"] ?: "默认标题" val message = remoteMessage.data["message"] ?: "默认内容" showNotification(title, message) } }
6. 检查设备与项目配置
- 确认设备系统设置中,你的App通知权限已开启,且对应通知渠道的重要性设为“高”;
- 验证
google-services.json文件已正确放置在app/目录下,且文件中的包名与build.gradle(Module)中的applicationId完全一致; - 在Firebase控制台发送测试消息时,选择“测试设备”并填入当前设备的FCM Token(可通过
onNewToken回调获取并打印),确保消息发送到目标设备。
内容的提问来源于stack exchange,提问作者Sargun Bhatti
相关产品推荐
相关产品推荐

