Android Studio中Firebase通知后台图标异常、大图不显示求助
解决Firebase通知前台正常、后台图标/大图失效的问题
我之前也踩过一模一样的坑!这种前台后台通知表现不一致的情况,核心原因是Firebase推送的两种payload处理逻辑完全不同:
- 前台时,消息会触发你的
FirebaseMessagingService,你可以完全自定义通知的所有内容; - 应用关闭/后台时,如果用的是
notification类型的payload,系统会直接接管通知展示,不会走你的自定义代码,这时候很多自定义配置就“失效”了。
下面分两个问题给你针对性的解决方案:
一、后台通知图标变成默认占位图
这个问题90%是因为你没配置Firebase的默认通知图标,或者图标不符合要求:
- 首先,你的通知图标必须是纯白色的矢量图(不能带任何背景色,否则系统会自动替换成占位球),放在
res/drawable或者mipmap目录下; - 然后在
AndroidManifest.xml里配置Firebase的默认通知图标和颜色:
<application ...> <!-- 配置默认通知图标 --> <meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@drawable/ic_your_notification_icon" /> <!-- 配置通知图标显示的颜色(可选,但推荐) --> <meta-data android:name="com.google.firebase.messaging.default_notification_color" android:resource="@color/your_notification_color" /> </application>
- 如果你是用
notificationpayload推送,还要确保payload里的icon字段和你配置的图标名称一致(比如"icon": "ic_your_notification_icon")。
二、后台通知大图无法显示
Firebase的notification payload本身不支持直接设置大图这类高级样式,要解决这个问题,你必须改用**data类型的payload**,然后自己接管所有通知的构建逻辑:
- 推送时只传
data字段,比如:
{ "data": { "title": "你的通知标题", "body": "你的通知内容", "image_url": "https://your-image-url.com/big_image.jpg", "priority": "high" }, "to": "用户的FCM令牌" }
注意一定要把priority设为high,这样应用关闭时系统才会唤醒你的Service处理消息。
- 自定义
FirebaseMessagingService,在onMessageReceived里手动构建带大图的通知:
class MyFirebaseMessagingService : FirebaseMessagingService() { private val CHANNEL_ID = "your_notification_channel_id" override fun onMessageReceived(remoteMessage: RemoteMessage) { super.onMessageReceived(remoteMessage) // 从data中取出所需参数 val title = remoteMessage.data["title"] ?: "默认标题" val body = remoteMessage.data["body"] ?: "默认内容" val imageUrl = remoteMessage.data["image_url"] // 初始化通知构建器 val notificationBuilder = NotificationCompat.Builder(this, CHANNEL_ID) .setSmallIcon(R.drawable.ic_your_notification_icon) .setContentTitle(title) .setContentText(body) .setPriority(NotificationCompat.PRIORITY_HIGH) .setAutoCancel(true) // 处理大图逻辑(异步加载图片,避免阻塞主线程) imageUrl?.let { url -> // 这里用Glide异步加载图片,你也可以用Picasso或者自己实现 Glide.with(this) .asBitmap() .load(url) .into(object : CustomTarget<Bitmap>() { override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) { val bigPictureStyle = NotificationCompat.BigPictureStyle() .bigPicture(resource) .bigLargeIcon(null) // 避免大图模式下重复显示小图标 notificationBuilder.setStyle(bigPictureStyle) // 显示通知 showNotification(notificationBuilder.build()) } override fun onLoadCleared(placeholder: Drawable?) {} }) } ?: run { // 如果没有大图,直接显示普通通知 showNotification(notificationBuilder.build()) } } private fun showNotification(notification: Notification) { val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager // 适配Android O及以上的通知渠道 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val channel = NotificationChannel( CHANNEL_ID, "你的通知渠道名称", NotificationManager.IMPORTANCE_HIGH ) notificationManager.createNotificationChannel(channel) } notificationManager.notify(System.currentTimeMillis().toInt(), notification) } }
- 别忘了在
AndroidManifest.xml里注册这个Service:
<service android:name=".MyFirebaseMessagingService" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service>
最后再提醒几个关键点
- 测试后台通知时,一定要完全关闭应用(不要在后台挂着),不然可能还是走前台逻辑;
- 图标一定要用纯白矢量图,别用带背景的图片,系统会自动过滤掉非白色部分;
- 如果你必须用
notificationpayload,那大图是没法实现的,只能改用datapayload全自定义。
内容的提问来源于stack exchange,提问作者Dennis muroni
相关产品推荐
相关产品推荐

