FCM HTTP v1 API与PHP多播消息适配问题咨询
新版FCM API多播支持及批量推送最优方案
核心问题解答
新版FCM API完全支持多播消息:旧版的
registration_ids字段对应新版的tokens字段,通过sendMulticast(针对同内容多设备)或sendAll(针对多设备自定义内容)端点实现批量推送,单次请求最多可包含500个设备令牌,完全覆盖你300-400个客户端的需求,不需要调用300-400次谷歌服务器。1分钟内推送300-400个客户端的最优方案:优先使用Firebase Admin SDK for PHP,其次是原生CURL调用HTTP v1 API,两种方式都能通过单次请求完成推送。
方案一:使用Firebase Admin SDK for PHP(推荐)
SDK会自动处理OAuth2令牌的获取与刷新,无需手动维护认证逻辑,代码简洁且稳定。
步骤:
- 安装SDK:
composer require kreait/firebase-php
- 编写推送代码:
<?php require __DIR__.'/vendor/autoload.php'; use Firebase\Admin\Credentials; use Firebase\Admin\FirebaseAdmin; use Firebase\Admin\Messaging\MulticastMessage; use Firebase\Admin\Messaging\Notification; // 初始化Admin SDK(替换为你的服务账号JSON路径) $cred = Credentials::fromJsonFile('/path/to/your-service-account.json'); FirebaseAdmin::initializeApp($cred); // 准备目标设备令牌列表(300-400个) $deviceTokens = [ 'token_xxxxxx', 'token_yyyyyy', // ... 其他令牌 ]; // 创建多播通知消息 $multicastMessage = MulticastMessage::new() ->setNotification(Notification::new() ->setTitle('你的通知标题') ->setBody('你的通知内容')) // 可选:配置Android专属通知参数(如渠道ID) ->setAndroid([ 'notification' => [ 'channel_id' => 'your_notification_channel_id' ] ]) ->setTokens($deviceTokens); // 发送消息并处理结果 $messaging = Firebase\Admin\Messaging\Messaging::getInstance(); $response = $messaging->sendMulticast($multicastMessage); // 输出推送统计 echo "成功推送: {$response->successCount()} 条\n"; echo "推送失败: {$response->failureCount()} 条\n"; // 遍历失败条目,排查无效令牌 foreach ($response->failures() as $failure) { echo "令牌 {$failure->token()} 失败原因: {$failure->reason()->getMessage()}\n"; } ?>
方案二:原生CURL调用FCM HTTP v1 API
若不想依赖SDK,可手动实现认证与推送逻辑。
步骤:
- 获取OAuth2访问令牌(有效期1小时,可缓存避免重复请求):
<?php // 替换为你的服务账号JSON路径 $serviceAccount = json_decode(file_get_contents('/path/to/your-service-account.json'), true); // 构建JWT令牌 $header = base64_encode(json_encode(['alg' => 'RS256', 'typ' => 'JWT'])); $payload = base64_encode(json_encode([ 'iss' => $serviceAccount['client_email'], 'scope' => 'https://www.googleapis.com/auth/firebase.messaging', 'aud' => 'https://oauth2.googleapis.com/token', 'exp' => time() + 3600, 'iat' => time() ])); $signature = ''; openssl_sign($header . '.' . $payload, $signature, $serviceAccount['private_key'], OPENSSL_ALGO_SHA256); $jwt = $header . '.' . $payload . '.' . base64_encode($signature); // 请求获取访问令牌 $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); $tokenData = json_decode(curl_exec($ch), true); curl_close($ch); $accessToken = $tokenData['access_token']; ?>
- 发送多播消息:
<?php // 替换为你的Firebase项目ID $projectId = 'your-firebase-project-id'; $deviceTokens = [/* 300-400个令牌 */]; // 构建请求体 $requestBody = json_encode([ 'message' => [ 'notification' => [ 'title' => '你的通知标题', 'body' => '你的通知内容' ], 'android' => [ 'notification' => [ 'channel_id' => 'your_notification_channel_id' ] ] ], 'tokens' => $deviceTokens ]); // 发起推送请求 $ch = curl_init("https://fcm.googleapis.com/v1/projects/{$projectId}/messages:sendMulticast"); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $requestBody); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Authorization: Bearer {$accessToken}", "Content-Type: application/json" ]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = json_decode(curl_exec($ch), true); curl_close($ch); // 处理响应 echo "成功数: {$response['successCount']}\n"; echo "失败数: {$response['failureCount']}\n"; ?>
注意事项
- 单次
sendMulticast请求最多支持500个令牌,你的300-400个令牌无需拆分请求 - 定期清理无效令牌(如推送失败的令牌),避免后续请求浪费资源
- Cron任务需确保执行时间在1分钟内,两种方案的效率均能满足该量级的推送需求
内容的提问来源于stack exchange,提问作者Cristian
相关产品推荐
相关产品推荐

