FCM迁移至HTTPv1后如何实现主题订阅?
解决FCM V1 API订阅主题的401授权问题
核心问题分析
你当前的问题在于:旧的IID API(https://iid.googleapis.com/iid/v1/...)在FCM V1时代已不再支持Server Key或普通推送令牌授权,必须使用具备firebase.messaging权限的服务账号Bearer令牌;同时更推荐使用FCM V1官方的主题管理端点或Firebase Admin SDK来处理订阅,避免手动处理授权的麻烦。
解决方案1:使用Firebase Admin SDK(PHP,推荐)
这是最简便的方式,SDK会自动处理授权和请求逻辑:
- 安装SDK
composer require kreait/firebase-php
- 初始化SDK并订阅主题
use Kreait\Firebase\Factory; // 加载服务账号密钥文件(从Firebase控制台下载) $factory = (new Factory)->withServiceAccount('/path/to/your-service-account.json'); $messaging = $factory->createMessaging(); // 订阅单个/多个设备令牌到指定主题 $deviceTokens = ['你的设备令牌']; $topicName = '目标主题名'; try { $result = $messaging->subscribeToTopic($topicName, $deviceTokens); echo "成功订阅 {$result->successCount()} 个令牌"; } catch (\Exception $e) { echo "订阅失败:{$e->getMessage()}"; }
解决方案2:手动调用FCM V1主题管理API
如果不想依赖SDK,可直接调用V1官方端点:
- 生成具备
firebase.messaging权限的Bearer令牌
use Firebase\JWT\JWT; $serviceAccount = json_decode(file_get_contents('/path/to/your-service-account.json'), true); $privateKey = $serviceAccount['private_key']; // 构造JWT payload $payload = [ 'iss' => $serviceAccount['client_email'], 'sub' => $serviceAccount['client_email'], 'aud' => 'https://oauth2.googleapis.com/token', 'iat' => time(), 'exp' => time() + 3600, // 令牌有效期1小时 'scope' => 'https://www.googleapis.com/auth/firebase.messaging' ]; // 生成JWT并交换为access token $jwt = JWT::encode($payload, $privateKey, 'RS256'); $ch = curl_init('https://oauth2.googleapis.com/token'); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([ 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', 'assertion' => $jwt ])); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $tokenResp = json_decode(curl_exec($ch), true); curl_close($ch); $accessToken = $tokenResp['access_token'];
- 调用V1批量订阅端点
$projectId = '你的Firebase项目ID'; $topicName = '目标主题名'; $deviceTokens = ['你的设备令牌']; $url = "https://fcm.googleapis.com/v1/projects/{$projectId}/topics/{$topicName}:batchAdd"; $payload = json_encode(['tokens' => $deviceTokens]); $ch = curl_init($url); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Authorization: Bearer {$accessToken}", 'Content-Type: application/json' ]); curl_setopt($ch, CURLOPT_POSTFIELDS, $payload); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch); echo $response;
之前尝试失败的原因
- 你用于发送通知的令牌可能仅包含
cloud-platform等通用权限,缺少firebase.messaging专属权限,无法操作主题订阅; - FCM V1时代的IID API已不再支持API Key授权,必须使用服务账号生成的Bearer令牌。
内容的提问来源于stack exchange,提问作者Mudassir
相关产品推荐
相关产品推荐

