如何在PHP REST API中通过Google REST API实现FCM REST API认证?
问题描述
我需要使用FCM REST API发送通知,但用API key认证失败。调用的接口是:
https://fcm.googleapis.com/v1/projects/proj-name/messages:send?key=XXX
收到的错误信息:
{ "error": { "code": 401, "message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.", "status": "UNAUTHENTICATED" } }
我的后端是PHP,没有可用的官方支持包,尝试直接调用接口但遇到认证问题。查文档知道需要用服务账号生成短期OAuth 2.0访问令牌,但文档没给PHP的具体实现方法,请问怎么在PHP里完成认证并发送通知?
解决方案
FCM v1 API不支持URL参数里的API key认证,必须用OAuth 2.0访问令牌,以下是PHP中的具体实现步骤:
1. 获取服务账号密钥文件
进入谷歌云控制台,找到你的Firebase项目,依次进入「IAM与管理」→「服务账号」,创建或使用现有服务账号,为其添加「Firebase Cloud Messaging Admin」权限,然后下载JSON格式的密钥文件,保存到PHP项目目录(注意不要暴露到公网)。
2. 安装Google Auth PHP库
使用Composer安装官方维护的认证库,这是最可靠的令牌生成方式:
composer require google/auth
若无法使用Composer,可手动引入库的源码,但优先推荐Composer管理依赖。
3. 编写代码生成令牌并发送通知
以下是完整示例代码:
<?php require __DIR__ . '/vendor/autoload.php'; use Google\Auth\Credentials\ServiceAccountCredentials; use GuzzleHttp\Client; // 服务账号密钥文件路径 $keyFilePath = __DIR__ . '/service-account-key.json'; // FCM OAuth 2.0 授权作用域 $scope = 'https://www.googleapis.com/auth/firebase.messaging'; // 初始化服务账号凭证 $credentials = new ServiceAccountCredentials($scope, $keyFilePath); // 获取短期访问令牌(有效期约1小时,建议缓存复用) $token = $credentials->fetchAuthToken()['access_token']; // FCM API 请求地址 $fcmUrl = 'https://fcm.googleapis.com/v1/projects/proj-name/messages:send'; // 构建通知内容 $notificationPayload = [ 'message' => [ 'token' => '目标设备的FCM令牌', 'notification' => [ 'title' => '测试通知', 'body' => '这是一条来自PHP后端的FCM通知' ] ] ]; // 发送请求 $client = new Client(); $response = $client->post($fcmUrl, [ 'headers' => [ 'Authorization' => 'Bearer ' . $token, 'Content-Type' => 'application/json' ], 'json' => $notificationPayload ]); // 输出响应结果 echo $response->getBody(); ?>
4. 关键注意事项
- 令牌缓存:访问令牌有效期为3600秒,不要每次请求都重新生成,建议将令牌存入Redis、文件缓存等介质,过期后再重新获取,避免频繁调用谷歌认证接口。
- 权限校验:确保服务账号已配置「Firebase Cloud Messaging Admin」权限,否则会触发权限不足的错误。
- 安全防护:服务账号密钥文件是敏感信息,禁止提交到版本库或暴露给前端,需设置严格的文件访问权限(仅PHP进程可读)。
内容的提问来源于stack exchange,提问作者Ariel
相关产品推荐
相关产品推荐

