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

使用PHP调用FCM HTTP v1 API时遇非法/格式错误请求问题

问题根源与解决方案

你的核心问题是Authorization请求头的用法完全错误——FCM HTTP v1 API要求的Bearer令牌是通过服务账号私钥生成的OAuth2访问令牌,不是直接把私钥文件的内容填进去。

推荐解决方案:使用Firebase Admin PHP SDK(最省心)

  1. 先安装SDK:
composer require kreait/firebase-php
  1. 替换你的代码为以下正确实现:
<?php

require __DIR__.'/vendor/autoload.php';

use Kreait\Firebase\Factory;
use Kreait\Firebase\Messaging\CloudMessage;
use Kreait\Firebase\Messaging\Notification;

$serviceAccountKeyFile = 'C:\Users\Yaz\Downloads\<projectName>-f8312-65996b5966ea.json';

// 初始化Firebase实例,SDK会自动处理令牌生成
$factory = (new Factory)->withServiceAccount($serviceAccountKeyFile);
$messaging = $factory->createMessaging();

// 构建推送消息
$message = CloudMessage::withTarget('token', 'fH8TwZfXQniUvF6aYqbTOu:APA91bH-uLHe3-e9-3N_Szu6bHwKbA4voAog1mzTVbOyFDUGjwZpZe8XUB2-FF0YD2StieCdvU1gtmNN4cg-ILyb6DFh1SrZhBfHZkMQUcPc6FsINaE38iLq8xhG-ankRPE0ifVmEDij')
    ->withNotification(Notification::create('Your Notification Title', 'Your Notification Body'));

// 发送通知并处理结果
try {
    $response = $messaging->send($message);
    echo "通知发送成功:{$response}";
} catch (Exception $e) {
    echo "发送失败:{$e->getMessage()}";
}

手动生成令牌方案(适合理解原理,不推荐)

如果不想依赖SDK,需要自己完成令牌生成流程:

  • 从私钥JSON文件中提取client_email和private_key字段
  • 用RS256算法生成JWT,Payload需包含:
    • iss: 上述client_email
    • scope: https://www.googleapis.com/auth/firebase.messaging
    • aud: https://oauth2.googleapis.com/token
    • exp: 当前时间戳 + 3600(令牌有效期1小时)
    • iat: 当前时间戳
  • 向https://oauth2.googleapis.com/token发送POST请求,请求体为grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=生成的JWT,获取返回的access_token
  • 将该access_token作为Bearer值填入Authorization头,再请求FCM发送接口

为什么你之前的尝试无效?

  • Guzzle报错是因为Authorization头里塞的是私钥文件内容,不是合法的OAuth2令牌,导致请求头格式非法
  • 新建服务账号无法解决问题,因为错误根源不是私钥本身,而是你完全误解了私钥的使用方式——私钥是生成令牌的凭证,不是令牌本身

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 14:54:57