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

PHP接入Firebase FCM主题订阅持续出现401认证错误求助

FCM主题订阅401错误排查与解决

问题描述

我尝试用PHP实现FCM主题订阅,更新后的代码如下:

// Path to your service account key file (JSON)
$serviceAccountFile = PAD_PLUGIN_DIR . 'positive-notch-181410-2bc8875c71a4.json';

// Your FCM Topic name
$topicName = get_the_category($post_id)[0]->slug;

// Device token to subscribe
$deviceToken = 'fuEMCQmCT_m0H3fdoXqD9m:APA91bGITP85Q6y3Zg3_Ls9bjbPKMBylwHads9hQbkzDJCeeOtlHfJZqxX4hIAJMeOoKYCfm59ki95tOpNViORr6cy4ATuCaDAubCkj1pdXzQsrI1lMeesZYRt-B_vCJO6R55NLfZRoM';

// Initialize Google Client
$client = new Google_Client();
$client->setAuthConfig($serviceAccountFile);
$client->addScope('https://www.googleapis.com/auth/firebase.messaging');

// Get an OAuth2 access token
$accessToken = $client->fetchAccessTokenWithAssertion();
$accessTokenString = $accessToken['access_token'];

$subscriptionUrl = 'https://iid.googleapis.com/iid/v1:batchAdd';

$data = [
    'to' => '/topics/blabla',
    'registration_tokens' => [$deviceToken]
];

$ch = curl_init($subscriptionUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer ' . $accessTokenString,
    'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($httpCode == 200) {
    echo "Successfully subscribed to topic.";
} else {
    echo "Failed to subscribe: " . $response;
}

exit;

执行后始终返回401错误,提示:
Authentication using server key is deprecated. Please use an OAuth2 token instead.

已确认$accessTokenString有效未过期,且拥有已启用FCM的Google Cloud项目及对应服务账户JSON密钥文件,请问问题出在哪里?


问题根源与解决步骤

1. 核心问题:使用了不支持OAuth2的旧API端点

你调用的https://iid.googleapis.com/iid/v1:batchAdd是旧版IID API端点,该端点仅支持已废弃的服务器密钥认证,不兼容OAuth2令牌,这是导致401错误的直接原因。必须替换为FCM v1 API的官方订阅端点。

2. 具体修正操作

  • 更换API端点:使用FCM v1规范的订阅端点,格式为:
    https://fcm.googleapis.com/v1/projects/{你的项目ID}/topics/{主题名称}:batchAdd
    项目ID可从服务账户JSON文件的project_id字段读取,或在Google Cloud控制台查看。

  • 修正请求体格式:FCM v1 API无需to字段,直接传入registration_tokens数组即可。

  • 修复主题名称硬编码:代码中定义了$topicName但未实际使用,需将请求体中的硬编码值替换为动态获取的主题名称。

3. 修正后的完整代码

// Path to your service account key file (JSON)
$serviceAccountFile = PAD_PLUGIN_DIR . 'positive-notch-181410-2bc8875c71a4.json';

// 从服务账户JSON读取项目ID(也可手动填写)
$serviceAccountData = json_decode(file_get_contents($serviceAccountFile), true);
$projectId = $serviceAccountData['project_id'];

// Your FCM Topic name
$topicName = get_the_category($post_id)[0]->slug;

// Device token to subscribe
$deviceToken = 'fuEMCQmCT_m0H3fdoXqD9m:APA91bGITP85Q6y3Zg3_Ls9bjbPKMBylwHads9hQbkzDJCeeOtlHfJZqxX4hIAJMeOoKYCfm59ki95tOpNViORr6cy4ATuCaDAubCkj1pdXzQsrI1lMeesZYRt-B_vCJO6R55NLfZRoM';

// Initialize Google Client
$client = new Google_Client();
$client->setAuthConfig($serviceAccountFile);
$client->addScope('https://www.googleapis.com/auth/firebase.messaging');

// Get an OAuth2 access token
$accessToken = $client->fetchAccessTokenWithAssertion();
$accessTokenString = $accessToken['access_token'];

// FCM v1 API主题订阅端点
$subscriptionUrl = "https://fcm.googleapis.com/v1/projects/{$projectId}/topics/{$topicName}:batchAdd";

// 符合v1规范的请求体
$data = [
    'registration_tokens' => [$deviceToken]
];

$ch = curl_init($subscriptionUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer ' . $accessTokenString,
    'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($httpCode == 200) {
    echo "Successfully subscribed to topic.";
} else {
    echo "Failed to subscribe: " . $response;
}

exit;

4. 额外验证项

  • 确认服务账户已分配Firebase Messaging Admin角色,或至少拥有firebase.messaging.topics.update权限
  • 检查$topicName是否正确获取到分类slug,避免空值或无效字符

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 13:27:31