调用Firebase发送推送通知时收到HTTP 400响应,PHP脚本格式是否正确?
问题分析与修复方案
HTTP 400错误通常是请求格式或授权信息不正确导致的,你的代码存在几个关键问题:
1. 授权方式完全错误
你直接使用了Firebase服务账号的private_key作为API_ACCESS_KEY,但FCM传统API(fcm/send端点)需要的是Firebase控制台里的服务器密钥,而非服务账号私钥。服务账号私钥仅适用于FCM HTTP v1 API,且需先生成OAuth2令牌才能使用,不能直接放在Authorization头中。
解决方法:
登录Firebase控制台 → 项目设置 → 云消息传递 → 复制服务器密钥(Legacy server key),替换当前从JSON文件读取的private_key。
2. 代码变量错误
成功分支中你输出了未定义的$response变量,应改为$result,否则会触发PHP警告。
3. 不必要的安全风险
CURLOPT_SSL_VERIFYPEER设为false会关闭SSL证书验证,易遭受中间人攻击,建议删除该行或设为true。
4. 数据结构冗余问题
notification和data字段重复了title和body,虽不会直接引发错误,但属于冗余设计。另外data中的priority字段多余,优先级已在根节点设置priority:10(对应高优先级)。
修正后的代码
function sendGCM($location, $vendor, $id) { // 替换为Firebase控制台获取的服务器密钥 $API_ACCESS_KEY = "你的Firebase服务器密钥"; $notification = [ 'title' => "你的午餐到了!", 'body' => $vendor . " 已经抵达 " . $location, 'sound' => "default" // 可选,开启通知声音 ]; $data = [ // 存放自定义业务数据,无需重复notification内容 'vendor' => $vendor, 'location' => $location ]; $fcmNotification = [ 'to' => $id, 'notification' => $notification, 'data' => $data, 'priority' => 10 ]; $headers = [ 'Authorization: key=' . $API_ACCESS_KEY, 'Content-Type: application/json' ]; $fcmUrl = "https://fcm.googleapis.com/fcm/send"; $ch = curl_init(); curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); curl_setopt($ch, CURLOPT_URL, $fcmUrl); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fcmNotification)); $result = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($httpCode != 200) { echo "返回码: {$httpCode} \n" . curl_error($ch); } else { echo "<pre>" . htmlspecialchars($result) . "</pre>"; } curl_close($ch); }
额外排查点
- 确认
$id是有效的FCM设备令牌,无效令牌也可能导致400错误。 - 检查请求JSON格式,确保没有语法错误(比如你注释里用了中文引号
“,若启用会导致JSON解析失败)。
内容的提问来源于stack exchange,提问作者HillInHarwich
相关产品推荐
相关产品推荐

