使用 v1 API 中的 cURL 将 Push FCM 发送到多个设备

lab*_*u77 5 curl firebase firebase-cloud-messaging

我需要将 FCM 推送通知发送到多个设备。我不能为此使用“主题”,因为我需要将其发送到特定的和多个令牌。

在旧方法中,我使用“register_ids”来实现此目的,但 Google 在 2023 年 6 月 20 日宣布,旧方法将于 2024 年 6 月 20 日结束。在新的 v1 API 中,不再支持“register_ids”。

我需要的是一个使用 cURL 和 PHP 向多个令牌发送推送通知的解决方案。

在这个网站上,有人问了和我类似的问题:

FCM 批量消息 URL

@Frank van Puffelen 说:

在这个新的版本化 API 中,您可以通过向常规端点发送多部分请求来发送多条消息。此过程在有关发送批量消息的部分中有完整记录,并且大多数可用的管理 SDK 也支持该过程.

Frank von Puffelen 提供了一个链接:

https://firebase.google.com/docs/cloud-messaging/send-message#send-a-batch-of-messages

然而,现在该网站上有一条说明:

本节中描述的批量发送方法已于 2023 年 6 月 21 日弃用,并将于 2024 年 6 月删除。相反,请通过实现您自己的批量发送逻辑、迭代收件人列表发送到每个收件人的令牌。对于 Admin SDK 方法,请确保更新到下一个主要版本。

在该网站的更上方,有一个标题为“向多个设备发送消息”的部分。但是,本节仅提供 Node.js、Java、Python、Go、C# 和 REST 的解决方案。我需要 PHP 和 cURL 的解决方案。

到目前为止我已经尝试过如下,但由于架构错误而无法正常工作:

$tokens = array(
"token 1",
"token 2"
);

foreach ($tokens as $token) {
$data = json_encode(array(
"message" => array(
"token" => $token,
"notification" => array(
"title" => "New Message",
"body" => "New Text",
"image" => "https://example.com/test.jpg"
),
"data" => array(
"website_link" => "https://example.com/",
"icon" => "https://example.com/test.jpg"
)
)
));

$accessToken = file_get_contents("access_token.txt");

curl_setopt_array($curl, array(
CURLOPT_URL => 'https://fcm.googleapis.com/v1/projects/myapp/messages:send',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => $data,
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'Authorization: Bearer ' . $accessToken
),
));
}

$response = curl_exec($curl);
Run Code Online (Sandbox Code Playgroud)

我知道我可以为每个令牌循环 cURL 代码,但我相信这不是一个好的做法,因为它会多次触发“https://fcm.googleapis.com/v1/projects/myapp/messages:send”一排。

我更愿意收集所有代币并立即发送。有解决办法吗?

非常感谢。

lab*_*u77 4

我找到了一个解决方案,希望它能节省某人的时间。

编辑:很抱歉,这个解决方案明年也将被弃用。请参阅本主题的新解决方案:

Firebase HTTP v1 API 不再批量发送?

请查看本网站上的“向多个设备发送消息”部分:

https://firebase.google.com/docs/cloud-messaging/send-message#send-messages-to-multiple-devices

重点关注其余部分。

使用此示例,我在同一 REST API 架构中实现了 foreach 循环。在这种情况下,您不需要 cURL 的batch_request.txt 文件。

该代码唯一需要的是设备令牌数组和不记名访问令牌。为了获取访问令牌,我从 Peter Bruins 找到了这个 PHP 函数:

为 Firebase Messaging 生成访问令牌

确保更改代码的以下部分以匹配您的应用程序名称:

$request .= "POST /v1/projects/your-app/messages:send\r\n";
Run Code Online (Sandbox Code Playgroud)

这是 PHP cURL FCM v1 API 解决方案:

$deviceTokens = 'yourarrayoftokens';

foreach ($deviceTokens as $token) {
  $request .= "\r\n--subrequest_boundary\r\n";
  $request .= "Content-Type: application/http\r\n";
  $request .= "Content-Transfer-Encoding: binary\r\n\r\n";
  $request .= "POST /v1/projects/your-app/messages:send\r\n";
  $request .= "Content-Type: application/json\r\n";
  $request .= "accept: application/json\r\n\r\n";
  $request .= '{
    "message":{
       "token":"' . $token . '",
       "notification":{
         "title":"FCM Push Test",
         "body":"This is only a test",
         "image":"http://example.com/1.jpg"
       }
    }
}';
}

$request .= "\r\n\r\n--subrequest_boundary--";

$curl = curl_init();

$accessToken = file_get_contents("bearer_token.txt");

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://fcm.googleapis.com/batch',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS => $request,
  CURLOPT_HTTPHEADER => array(
    'Content-Type: multipart/mixed; boundary="subrequest_boundary"',
    'Authorization: Bearer ' . $accessToken 
  ),
));

$response = curl_exec($curl);
echo $response . '<br />';
Run Code Online (Sandbox Code Playgroud)

我希望“https://fcm.googleapis.com/batch”在不久的将来不会被弃用。根据我的理解,唯一需要的更改是将“https://fcm.googleapis.com/send”替换为“/v1/projects/your-app/messages:send”,而“https://fcm.googleapis.com” /batch”仍然可以使用。如果我错了,请纠正我。Google 推荐此解决方案,并在其官方文档中将其作为推荐方法提供。(请参阅以下行末尾的 url)

curl --data-binary @batch_request.txt -H 'Content-Type: multipart/mixed; boundary="subrequest_boundary"' -H 'Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA' https://fcm.googleapis.com/batch
Run Code Online (Sandbox Code Playgroud)

如果有人需要 foreach 数据而不是通知,请使用以下 foreach:

foreach ($deviceTokens as $token) {
  $request .= "\r\n--subrequest_boundary\r\n";
  $request .= "Content-Type: application/http\r\n";
  $request .= "Content-Transfer-Encoding: binary\r\n\r\n";
  $request .= "POST /v1/projects/my-app/messages:send\r\n";
  $request .= "Content-Type: application/json\r\n";
  $request .= "accept: application/json\r\n\r\n";
  $request .= '{
    "message":{
       "token":"' . $token . '",
       "data":{
         "message_title":"Test",
         "message_body":"Test",
         "website_link":"example.com", 
         "notification_type":"message",
         "image":"example.com/1.jpg"
       }
    }
}';
}
Run Code Online (Sandbox Code Playgroud)