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

FCM通知仅在应用后台/未打开时送达,如何实现前台显示标准通知?

FCM前台接收通知问题解决方案

问题结论

这不是FCM通知的正常表现,应用前台运行时完全可以接收并展示标准通知,只是默认情况下纯通知消息不会自动弹出,需要手动添加代码处理。

核心原理

FCM消息分为两类:

  • 通知消息:仅包含notification字段,后台时由系统托盘自动展示;前台时不会自动弹出,需开发者手动处理展示逻辑。
  • 数据消息/混合消息:包含data字段(或同时包含notification+data),无论前台后台都会触发自定义回调,开发者可在回调中自由处理通知展示。

平台具体实现

Android端

  1. 创建FirebaseMessagingService子类,重写onMessageReceived方法,在该方法中手动构建并显示通知:
class MyFirebaseMessagingService : FirebaseMessagingService() {
    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        super.onMessageReceived(remoteMessage)
        
        // 处理控制台发送的纯通知消息
        remoteMessage.notification?.let {
            showNotification(it.title ?: "", it.body ?: "")
        }
        
        // 处理自定义数据消息(可选)
        if (remoteMessage.data.isNotEmpty()) {
            val title = remoteMessage.data["title"] ?: "新通知"
            val body = remoteMessage.data["body"] ?: "您有一条新消息"
            showNotification(title, body)
        }
    }
    
    private fun showNotification(title: String, body: String) {
        val intent = Intent(this, MainActivity::class.java).apply {
            addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
        }
        val pendingIntent = PendingIntent.getActivity(
            this, 0, intent,
            PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
        )
        
        val channelId = "default_notification_channel"
        val notificationBuilder = NotificationCompat.Builder(this, channelId)
            .setSmallIcon(R.drawable.ic_notification)
            .setContentTitle(title)
            .setContentText(body)
            .setAutoCancel(true)
            .setContentIntent(pendingIntent)
        
        val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        
        // Android O及以上需创建通知渠道
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                channelId, "默认通知渠道",
                NotificationManager.IMPORTANCE_DEFAULT
            )
            notificationManager.createNotificationChannel(channel)
        }
        
        notificationManager.notify(0, notificationBuilder.build())
    }
}
  1. 在AndroidManifest.xml中注册该服务:
<service
    android:name=".MyFirebaseMessagingService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

iOS端

  1. 在AppDelegate中实现UNUserNotificationCenterDelegate的willPresent方法,指定前台通知的展示方式:
import UserNotifications
import FirebaseMessaging

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, MessagingDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        FirebaseApp.configure()
        Messaging.messaging().delegate = self
        
        // 请求通知权限并设置代理
        UNUserNotificationCenter.current().delegate = self
        let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
        UNUserNotificationCenter.current().requestAuthorization(options: authOptions) { _, _ in }
        application.registerForRemoteNotifications()
        
        return true
    }
    
    // 前台收到通知时触发,配置展示选项
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        // 允许弹窗、声音、角标展示
        completionHandler([.alert, .sound, .badge])
    }
}

额外说明

使用Firebase控制台的「Send test message」发送的是纯通知消息,按上述代码处理后,前台就能正常弹出通知。如果是自建服务器发送消息,也可以选择发送包含data字段的混合消息,实现前后台统一处理逻辑。


内容的提问来源于stack exchange,提问作者Timow

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 16:00:51