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

PHP实现向所有Android设备发送Firebase推送通知

代码问题排查

你写的代码存在以下几个直接导致推送失效的问题:

  • 认证头格式错误:Authorization字段中key=和你的服务器密钥之间多了空格,FCM接口会直接返回401认证失败
  • 参数位置与类型错误:priority、content_available是推送请求的顶层参数,你错误放到了data数组里;且priority传了数字值10,FCM接口仅接受字符串类型的high/normal,数字值会被直接丢弃,导致推送优先级过低被Android系统拦截
  • 冗余无效字段:notification数组里的alert是iOS APNs专属字段,Android端无识别逻辑,多余字段可能触发接口解析异常
  • 全量推送逻辑缺失:你指定推送到/topics/alerts主题,但没有保证所有安装App的Android设备都订阅了该主题,未订阅设备完全收不到消息,自然无法实现全量推送
  • 无错误捕获逻辑:代码没有打印curl请求错误、FCM接口返回的错误信息,出问题后无法定位根因
全量Android设备推送实现方案

实现全量推送成本最低的方案是主题推送:所有Android设备启动App时固定订阅同一个全局主题,服务端直接向该主题发消息即可触达所有设备,不需要自行维护设备Token列表。

客户端前置配置

在Flutter端Firebase Messaging初始化逻辑中,添加全局主题订阅代码,确保每个用户启动App都会执行:

// 放在Firebase初始化完成后执行即可
await FirebaseMessaging.instance.subscribeToTopic('all_android_devices');

如果你已经创建了Android高优先级通知渠道,把渠道ID记下来,后面PHP代码里要对应上。

可用PHP推送代码

<?php
// FCM旧版HTTP接口地址,目前仍可正常使用
$fcmEndpoint = 'https://fcm.googleapis.com/fcm/send';
// 替换为Firebase控制台-项目设置-云消息传递页面下的「旧版服务器密钥」,不要加多余空格
$serverKey = '替换成你自己的服务器密钥';

// 通知栏展示的内容
$notificationPayload = [
    "title" => "通知标题",
    "body"  => "通知正文内容",
    "sound" => "default",
    // 如果你创建了自定义高优先级通知渠道,把下面这行的注释打开,值替换成你的渠道ID
    // "android_channel_id" => "high_importance_channel"
];

// 透传自定义数据,App前后台都能拿到,可做点击跳转、业务逻辑处理
$dataPayload = [
    "click_action" => "FLUTTER_NOTIFICATION_CLICK", // Flutter固定的通知点击动作标识,必须加否则点击通知无响应
    "redirect" => "/home", // 自定义字段示例:点击通知跳转到指定页面
    "msg_id" => uniqid() // 自定义消息唯一标识,可用于去重
];

// 完整请求体
$requestBody = [
    'to' => '/topics/all_android_devices', // 对应客户端订阅的全局主题
    'notification' => $notificationPayload,
    'data' => $dataPayload,
    'priority' => 'high', // 高优先级,Android端会尝试即时唤醒推送
    'content_available' => true,
    'android' => [
        'priority' => 'high',
        'notification' => [
            'default_sound' => true,
            'default_vibrate_timings' => true
        ]
    ]
];

$headers = [
    'Authorization: key=' . $serverKey, // *注意key=后直接拼接密钥,不能有空格*
    'Content-Type: application/json'
];

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $fcmEndpoint);
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_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($requestBody));

$response = curl_exec($ch);
// 捕获curl层错误
if (curl_errno($ch)) {
    echo "请求发送失败:" . curl_error($ch);
    exit;
}
curl_close($ch);

// 处理接口返回结果
$result = json_decode($response, true);
if (isset($result['success']) && $result['success'] === 1) {
    echo "推送成功,消息ID:" . $result['message_id'];
} else {
    echo "推送失败,接口返回:" . print_r($result, true);
}
?>
注意事项
  • 不要使用新版FCM HTTP v1接口的服务账号凭据做旧接口认证,必须用页面上标注的「旧版服务器密钥」
  • 主题消息最长延迟为30秒,属于FCM官方正常策略,不是代码问题
  • 用户清除App数据、卸载重装后,首次启动App会自动重新订阅全局主题,不需要额外处理
  • 如果需要定向推送给部分用户,再额外给用户打不同的主题标签即可
  • 不要在data字段中存放敏感信息,透传数据为明文传输

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 21:57:23