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

如何用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:11:28