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

FCM批量发送服务停用后,循环调用HTTP v1 API是否合规?

关于FCM HTTP v1 API逐条调用的合理性及代码优化建议

核心结论

逐条调用FCM HTTP v1 API是符合谷歌预期的可行方案,但你的当前代码存在几个关键问题需要修正,同时可以通过HTTP/2特性进一步优化性能。

为什么逐条调用是可行的?

谷歌推荐的FCM HTTP v1 API本身就是单条消息发送的设计,结合HTTP/2的多路复用特性,即使发起多个请求,底层也会复用同一个TCP连接,不会像HTTP/1.1那样产生大量连接开销。400条请求在HTTP/2下的性能表现和原批量接口差距不大,甚至在谷歌的扇出优化加持下,送达效率会更稳定。

当前代码的问题

  1. HTTP版本错误:你已启用HTTP/2,但代码强制设置CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,完全浪费了HTTP/2的多路复用优势,应改为CURL_HTTP_VERSION_2_0。
  2. Content-Type错误:FCM HTTP v1 API接收JSON格式请求体,不需要multipart/mixed类型,应改为Content-Type: application/json。
  3. 变量名不匹配:代码中生成的请求内容是$data,但POST字段用了未定义的$request,会导致请求体为空,发送失败。
  4. 资源重复创建:每次循环都初始化和关闭cURL句柄,即使HTTP/2也会影响连接复用效率,应把cURL初始化移到循环外。
  5. 字段格式错误:FCM的notification只支持标准字段(如title、body),自定义字段(website_link、notification_type)应放在data对象中,否则客户端可能无法解析。

优化后的代码示例

// 初始化cURL句柄(仅执行一次)
$curl = curl_init();

// 设置通用cURL选项
curl_setopt_array($curl, array(
    CURLOPT_URL => 'https://fcm.googleapis.com/v1/projects/my-app/messages:send',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_2_0, // 启用HTTP/2
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json', // 修正请求类型
        'Authorization: Bearer ' . $accessToken 
    ),
));

foreach ($deviceTokens as $token) {
    $data = json_encode(array(
        "message" => array(
            "token" => $token,
            "notification" => array(
                "title" => "Test", // 使用FCM标准字段名
                "body" => "Test", 
                "image" => "https://example.com/test.jpg" // 图片需完整HTTP/HTTPS URL
            ),
            "data" => array( // 自定义字段放入data对象
                "website_link" => "https://example.com", 
                "notification_type" => "message"
            )      
        )
    ));

    // 仅更新循环中变化的POST内容
    curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
    
    $response = curl_exec($curl);
    // 建议添加错误检测:if(curl_errno($curl)) { /* 处理错误 */ }
    echo $response . '<br />';
}

// 最后统一关闭cURL句柄
curl_close($curl);

额外注意事项

  • 速率限制:FCM有请求速率限制,400条属于小批量一般不会触发,但大批量发送时需监控响应中的Retry-After头,实现退重逻辑。
  • 批量替代方案:如果追求极致效率,可使用FCM的主题订阅或设备组功能,将同类设备分组后一次请求发送给多个设备,但需提前做好设备分组管理。
  • 错误处理:建议添加curl_error()检查请求是否失败,避免静默丢失消息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 22:17:01