如何通过 CURL 向所有设备发送 Firebase 通知?

How do you send a Firebase Notification to all devices via CURL?

我正在尝试向所有应用程序用户发送通知(在 Android 上),本质上是重复通过 Firebase 管理控制台发送通知时发生的情况。这是我开始使用的 CURL 命令:

curl --insecure --header "Authorization: key=AIzaSyBidmyauthkeyisfineL-6NcJxj-1JUvEM" --header "Content-Type:application/json" -d "{\"notification\":{\"title\":\"note-Title\",\"body\":\"note-Body\"}}" https://fcm.googleapis.com/fcm/send

这里是 JSON 解析出来的,让您看起来更舒服:

{
"notification":{
    "title":"note-Title",
    "body":"note-Body"
    }
}

返回的响应只有两个字符:

就是这样,"to"这个词。 (Headers 报告 400)我怀疑这与我的 JSON 中没有 "to" 有关。 "to" 甚至可以放什么?我没有定义主题,设备也没有注册任何东西。然而,他们仍然能够从 Firebase 管理面板接收通知。

由于 Firebase 通知处理的惊人限制,我想尝试 "data only" JSON 包,如果您的应用程序在前台,通知将由您的处理程序处理,但是如果您的应用程序在后台运行,它会由 Firebase 服务在内部进行处理,并且永远不会传递给您的通知处理程序。显然,如果您通过 API 提交通知请求,则可以解决此问题,但前提是您使用 data-only 提交通知请求。 (这会破坏使用相同消息处理 iOS 和 Android 的能力。)在我的 JSON 中用 "data" 替换 "notification" 没有任何效果。

好的,然后我尝试了这里的解决方案: 在我看来,"Ok, even though notifications to everyone is possible via the Admin console... it's not really possible via the API." 解决方法是让每个客户端订阅一个主题,然后将通知推送到该主题。所以首先是 onCreate 中的代码:

FirebaseMessaging.getInstance().subscribeToTopic("allDevices");

那么新的JSON我发:

{
"notification":{
    "title":"note-Title",
    "body":"note-Body"
    },
"to":"allDevices"
}

所以现在我至少从服务器得到了真实的响应。 JSON 回复:

{
"multicast_id":463numbersnumbers42000,
"success":0,
"failure":1,
"canonical_ids":0,
"results":
    [
    {
    "error":"InvalidRegistration"
    }
    ]
}

它带有 HTTP 代码 200。好的...根据 https://firebase.google.com/docs/cloud-messaging/http-server-ref,带有 "InvalidRegistration" 的 200 代码意味着注册令牌有问题。或许?因为那部分文档是针对消息传递服务器的。通知服务器是否相同?不清楚。我在其他地方看到该主题可能需要几个小时才能生效。似乎这会使它无法创建新的聊天室,所以看起来也不行。

当我以前从未使用过 Firebase 时,当我可以从头开始编写一个应用程序并在短短几个小时内收到通知时,我感到非常兴奋。在达到 Stripe.com 文档的水平之前,它似乎还有很长的路要走。

底线:有谁知道 JSON 可以提供什么来向所有设备发送消息 运行 反映管理控制台功能的应用程序?

Firebase 通知没有 API 来发送消息。幸运的是,它是建立在 Firebase Cloud Messaging 之上的,它恰好有这样一个 API.

借助 Firebase 通知和云消息传递,您可以通过三种方式向设备发送所谓的下游消息:

  1. to specific devices,如果你知道他们的设备 ID
  2. to groups of devices,如果你知道组的注册ID
  3. to topics,这些只是设备可以订阅的密钥

您会注意到无法明确发送到所有设备。不过,您可以使用其中的每一个来构建这样的功能,例如:通过在应用程序启动时订阅一个主题(例如 /topics/all)或通过保留所有设备 ID 的列表,然后将消息发送到所有那些。

要发送到主题,您的命令中存在语法错误。主题以 /topics/ 开头标识。由于您的代码中没有它,服务器会将 allDevices 解释为设备 ID。由于它是设备注册令牌的无效格式,因此会引发错误。

来自关于向主题发送消息的文档:

https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA

{
  "to": "/topics/foo-bar",
  "data": {
    "message": "This is a Firebase Cloud Messaging Topic Message!",
   }
}

您可以使用“/topics/all”向所有设备发送通知

https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA

{
  "to": "/topics/all",
  "notification":{ "title":"Notification title", "body":"Notification body", "sound":"default", "click_action":"FCM_PLUGIN_ACTIVITY", "icon":"fcm_push_icon" },
  "data": {
    "message": "This is a Firebase Cloud Messaging Topic Message!",
   }
}

一种方法是让所有用户的设备订阅一个主题。这样,当您将消息定位到特定主题时,所有设备都会收到它。我认为这是 Firebase 控制台中通知部分的工作方式。

我想出的向所有设备发送推送通知的最简单方法是为它们订阅一个主题 "all",然后向该主题发送通知。 将此复制到您的主 activity

FirebaseMessaging.getInstance().subscribeToTopic("all");

现在将请求发送为

{
   "to":"/topics/all",
   "data":
   {
      "title":"Your title",
      "message":"Your message"
      "image-url":"your_image_url"
   }
}

这可能是低效或非标准的方式,但正如我上面提到的,这是最简单的方式。如果您有任何更好的方法向所有 设备发送推送通知,请post。

如果您不熟悉使用 Firebase 云消息传递发送推送通知,则可以按照本教程进行操作 Tutorial - Push Notifications using FCM


要向组合 主题发送消息,请指定条件,这是一个指定目标主题的布尔表达式。例如,以下条件将向订阅 TopicATopicBTopicC 的设备发送消息:

{
   "data":
   {
      "title": "Your title",
      "message": "Your message"
      "image-url": "your_image_url"
   },
   "condition": "'TopicA' in topics && ('TopicB' in topics || 'TopicC' in topics)"
}

FCM documentation

上阅读有关条件和主题的更多信息

只需让所有登录的用户订阅特定主题,然后向该主题发送通知即可。

我正在为我的 Ionic Cordova 应用程序推送通知寻找解决方案。

感谢 Syed Rafay 的回答。

app.component.ts

const options: PushOptions = {
  android: {
    topics: ['all']
  },

服务器文件

"to" => "/topics/all",

编辑:似乎不再支持此方法(感谢@FernandoZamperin)。请看看其他答案!

您可以使用 condition 键并向不在组中的实例发送消息,而不是订阅主题。您的数据可能如下所示:

{
    "data": {
        "foo": "bar"
    },
    "condition": "!('anytopicyoudontwanttouse' in topics)"
}

https://firebase.google.com/docs/cloud-messaging/send-message#send_messages_to_topics_2

在 firebase 控制台上检查您的主题列表。

  1. 转到 firebase 控制台

  2. 单击侧面菜单中的增长

  3. 点击云消息

  4. 单击发送您的第一条消息

  5. 在通知部分,输入通知标题通知文本

  6. 点击下一步

  7. 在目标部分单击 主题

  8. 点击消息主题文本框,然后你可以看到你的主题(我没有创建名为android或[=79=的主题], 但我可以看到那两个主题。

  9. 当您发送推送通知时,将此添加为您的条件。

    "条件"=> "'all' 个主题 || 'android' 个主题 || 'ios' 个主题",

满body

array(
    "notification"=>array(
        "title"=>"Test",
        "body"=>"Test Body",
    ),
    "condition"=> "'all' in topics || 'android' in topics || 'ios' in topics",
);

如果您有更多主题可以添加带有||(或)条件的主题,那么所有用户都会收到您的通知。经过测试并为我工作。

对于任何想知道如何在 cordova 混合应用程序 中做到这一点的人:

  • 转到 index.js -> 函数内 onDeviceReady() 写入:

      subscribe();
    

(写在函数的最前面很重要!)

  • 然后,在同一个文件 (index.js) 中找到:

    函数订阅(){

     FirebasePlugin.subscribe("write_here_your_topic", function(){
    
     },function(error){
    
         logError("Failed to subscribe to topic", error);
     });
     }
    

并在此处写下您自己的主题 -> "write_here_your_topic"

这是一个 PHP Admin-SDK 示例,用于为用户订阅主题并通过设备令牌或主题向设备发送消息。请注意,主题是在您订阅用户时自动创建的。

$testTokens = ['device token 1', 'device token 2', ....]

// CREDENTIALS, YOU HAVE TO DOWNLOAD IT FROM FIREBASE CONSOLE.
$factory = (new Factory())->withServiceAccount('credentials.json');

$messaging = $factory->createMessaging();

// Subscribe a token or a group of tokens to a topic (this topic is created automatically if not exists)
// YOU CAN DO THIS IN THE MOBILE APP BUT IS BETTER DO IT IN THE API.
$result = $messaging->subscribeToTopic('all', $testTokens); // 'all' is the topic name

// Send a message to a specific Topic (Channel) 
$message = CloudMessage::withTarget('topic', 'all')
    ->withNotification(Notification::create('Global message Title', 'Global message Body'))
    ->withData(['key' => 'value']); // optional
$messaging->send($message);

// Send a message to a token or a grup of tokens (ONLY!!!)
 foreach($testTokens as $i=>$token){
     $message = CloudMessage::withTarget('token', $token)
         ->withNotification(Notification::create('This is the message Title', 'This is the message Body'))
         ->withData(['custom_index' => $i]); // optional
     $messaging->send($message);

您可以查看此存储库以了解更多详细信息:firebase-php-admin-sdk