PHP 7.4调用FCM HTTP v1 API时持续出现403 Forbidden错误排查
解决Drupal 7.x + PHP 7.4下Google API Client发送FCM报403 Forbidden的问题
以下是针对性的排查和解决步骤:
1. 锁定兼容PHP 7.4的Google API Client版本
Google API Client从v2.17.0开始要求PHP 8.0+,必须确保使用v2.16.0及以下的兼容版本:
- 检查
composer.json中的依赖配置,修改为:"google/apiclient": "^2.15" - 执行
composer update google/apiclient完成版本适配,避免因版本过高导致兼容性问题。
2. 校验Service Account权限与配置
403错误大多和权限直接相关,重点检查:
- IAM角色配置:登录Google Cloud Console,给service account授予
Firebase Cloud Messaging API Admin角色(不要用泛型的Editor/Owner,必须对应FCM的专属权限)。 - 密钥有效性:确认
service_account.json中的client_email未被禁用,私钥(private_key)未过期,文件本身无格式错误。 - 文件访问权限:确保Drupal运行的服务器用户(如
www-data)能读取该json文件,建议权限设为640,同时使用绝对路径引用文件,避免Drupal路径解析错误。
3. 替换file_get_contents为Guzzle HTTP客户端
很多服务器会禁用allow_url_fopen,导致Google API Client默认用file_get_contents发起请求失败,换成Guzzle可绕过这个限制:
- 安装兼容PHP7.4的Guzzle版本:
composer require guzzlehttp/guzzle:^6.5 - 初始化Google Client时指定Guzzle作为HTTP客户端:
require_once 'vendor/autoload.php'; $client = new Google_Client(); $client->setAuthConfig('/path/to/service_account.json'); $client->addScope('https://www.googleapis.com/auth/firebase.messaging'); // 替换默认HTTP客户端为Guzzle $client->setHttpClient(new GuzzleHttp\Client([ 'verify' => true, // 若服务器CA证书有问题,可指定证书路径或临时设为false(不推荐生产环境) 'timeout' => 30, ]));
4. 检查FCM请求格式与目标令牌
- 确认设备令牌(token)有效,未被FCM标记为无效(比如APP卸载后令牌失效会返回403)。
- 确保请求payload符合FCM v1 API规范,示例格式:
$message = [ 'message' => [ 'token' => 'DEVICE_TOKEN_HERE', 'notification' => [ 'title' => '测试通知', 'body' => '这是一条FCM测试通知' ] ] ];
5. 开启调试日志定位具体错误
开启Google Client的调试模式,获取完整的请求/响应细节,精准定位403原因:
$client->setDebug(true); // 或者将日志输出到文件 $debugLog = fopen('/tmp/google_api_debug.log', 'a'); $client->setDebug($debugLog);
查看日志可看到Google返回的具体错误描述,比如"Permission denied"、"API not enabled"等。
6. 确认Firebase Cloud Messaging API已启用
登录Google Cloud Console,进入「API和服务」->「库」,搜索并启用Firebase Cloud Messaging API,未启用API会直接返回403。
内容的提问来源于stack exchange,提问作者pavel murnikov
相关产品推荐
相关产品推荐

