You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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启动时提前创建渠道:

  1. 创建自定义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)
        }
    }
}
  1. 在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 13:17:51