FCM通知仅在应用后台/未打开时送达,如何实现前台显示标准通知?
FCM前台接收通知问题解决方案
问题结论
这不是FCM通知的正常表现,应用前台运行时完全可以接收并展示标准通知,只是默认情况下纯通知消息不会自动弹出,需要手动添加代码处理。
核心原理
FCM消息分为两类:
- 通知消息:仅包含
notification字段,后台时由系统托盘自动展示;前台时不会自动弹出,需开发者手动处理展示逻辑。 - 数据消息/混合消息:包含
data字段(或同时包含notification+data),无论前台后台都会触发自定义回调,开发者可在回调中自由处理通知展示。
平台具体实现
Android端
- 创建
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()) } }
- 在
AndroidManifest.xml中注册该服务:
<service android:name=".MyFirebaseMessagingService" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service>
iOS端
- 在
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
相关产品推荐
相关产品推荐

