如何用PHP发送带图片的FCM通知?现有代码无图片显示求解
解决FCM通知能接收但不显示图片的问题
嘿,我之前也遇到过一模一样的问题!FCM通知能收到但图片不显示,大多是因为图片字段的位置不对或者客户端没做对应处理,我来给你梳理下解决步骤:
1. 先改服务端代码:把图片字段放到正确的位置
你现在把image放在了notification对象里,但FCM的notification payload在Android上默认不会自动加载显示图片,正确的做法是把图片URL放到data对象中,同时保留notification里的基础通知内容。另外还要注意FCM的请求URL和图片URL的格式,我给你改好了代码:
修改后的PHP代码
<?php // 基础通知内容(标题、正文等) $notification = array( 'body' => 'here is a message. message', 'title' => 'This is a title', 'subtitle' => 'This is a subtitle. subtitle', 'vibrate' => 1, 'sound' => 1, 'icon' => 'https://your-domain.com/icon.png' // 这里要用可访问的HTTPS URL,或者Android应用内的资源名 ); // 自定义数据,存放图片URL $data = array( 'image' => 'https://your-domain.com/notification-image.png' // 必须是公开可访问的HTTPS地址! ); $fields = array( 'registration_ids' => array('id1','id2'), 'notification' => $notification, 'data' => $data // 把自定义数据加入请求体 ); $headers = array( 'Authorization: key=your-fcm-server-key', 'Content-Type: application/json' ); $ch = curl_init(); // 注意FCM的官方请求URL是这个,别填错了 curl_setopt($ch, CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send'); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields)); $result = curl_exec($ch); curl_close($ch); // 可以打印结果看看有没有错误 echo $result; ?>
2. 客户端必须做对应处理(关键!)
光改服务端没用,客户端得拿到data里的图片URL,然后加载显示到通知里,我给你举个Android的例子:
Android端处理示例(Kotlin)
在你的FirebaseMessagingService里的onMessageReceived方法中,解析图片URL并构建带图片的通知:
override fun onMessageReceived(remoteMessage: RemoteMessage) { super.onMessageReceived(remoteMessage) // 拿到通知的标题和正文 val title = remoteMessage.notification?.title ?: "默认标题" val body = remoteMessage.notification?.body ?: "默认正文" // 拿到data里的图片URL val imageUrl = remoteMessage.data["image"] // 构建通知 val notificationBuilder = NotificationCompat.Builder(this, "your_notification_channel_id") .setSmallIcon(R.drawable.ic_notification_icon) // 应用内的小图标 .setContentTitle(title) .setContentText(body) .setPriority(NotificationCompat.PRIORITY_HIGH) .setAutoCancel(true) // 如果有图片URL,就加载并显示大图 imageUrl?.takeIf { it.isNotEmpty() }?.let { url -> // 用Glide加载图片(也可以用Picasso) val bitmap = Glide.with(this) .asBitmap() .load(url) .submit() .get() // 设置大图样式 notificationBuilder.setStyle( NotificationCompat.BigPictureStyle() .bigPicture(bitmap) .bigLargeIcon(null) // 隐藏大图模式下的小图标 ) // 也可以设置通知的大图标 notificationBuilder.setLargeIcon(bitmap) } // 显示通知 val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager notificationManager.notify(System.currentTimeMillis().toInt(), notificationBuilder.build()) }
iOS端说明
iOS的话,如果把image放在notification对象里,FCM会自动转成APNs的mutable-content,iOS系统会自动加载显示图片,但要确保图片是HTTPS且可访问。如果用data字段,iOS也需要在didReceiveRemoteNotification里解析并处理。
3. 几个容易踩坑的检查点
- 图片URL必须是HTTPS:HTTP的URL在大部分设备上会被拦截,加载失败
- 图片要公开可访问:别用需要登录或者有防盗链的URL,FCM和客户端都没法访问
- FCM服务器密钥要正确:去Firebase控制台的「云消息传递」里复制正确的服务器密钥,别用Web API密钥
- 通知渠道(Android):Android 8.0以上必须创建通知渠道,否则通知可能不显示
额外小技巧:如果想直接用notification payload显示图片
如果只针对iOS,或者某些Android版本,也可以试试把image直接放在notification对象里,比如:
$notification = array( // ...其他字段 'image' => 'https://your-domain.com/image.png' );
这种情况iOS会自动显示图片,但Android还是需要客户端处理,所以更推荐用data字段的方式,兼容性更好。
内容的提问来源于stack exchange,提问作者Charlize Smith
相关产品推荐
相关产品推荐

