103

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

curl --insecure --header "授权: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"
    }
}

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

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

由于 Firebase 通知处理的惊人限制,我想尝试一个“仅数据”的 JSON 包,如果您的应用程序在前台,通知将由您的处理程序处理,但如果您的应用程序在后台,它会得到由 Firebase 服务在内部处理,并且从未传递给您的通知处理程序。显然,如果您通过 API 提交通知请求,则可以解决此问题,但前提是您仅使用数据执行此操作。(这会破坏使用相同消息处理 iOS 和 Android 的能力。)在我的任何 JSON 中用“数据”替换“通知”都没有效果。

好的,然后我在这里尝试了解决方案:Firebase Java Server to send push notification to all devices 在我看来,“好的,即使可以通过管理控制台向所有人发送通知......通过 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 来向所有运行应用程序的设备发送消息以反映管理控制台功能?

4

10 回答 10

112

Firebase Notifications 没有用于发送消息的 API。幸运的是,它建立在 Firebase Cloud Messaging 之上,而 Firebase Cloud Messaging 正是拥有这样的 API。

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

  1. 到特定设备,如果您知道它们的设备 ID
  2. 到设备组,如果您知道组的注册 ID
  3. 到主题,它们只是设备可以订阅的键

您会注意到,无法显式发送到所有设备。不过,您可以使用其中的每一个来构建此类功能,例如:通过在应用启动时订阅主题(例如/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!",
   }
}
于 2016-07-07T14:36:26.937 回答
82

我想出的向所有设备发送推送通知的最简单方法是将它们订阅到“全部”主题,然后向该主题发送通知。将此复制到您的主要活动中

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

现在发送请求为

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

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

如果您不熟悉使用 Firebase 云消息传递教程 - 使用 FCM 推送通知来发送推送通知,您可以学习本教程


要将消息发送到主题组合,请指定条件,它是指定目标主题的布尔表达式。例如,以下条件将向订阅的设备发送消息TopicATopicB或者TopicC

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

在FCM 文档中阅读有关条件和主题的更多信息

于 2017-12-24T18:44:35.677 回答
62

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

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

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

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

于 2019-08-26T21:27:35.867 回答
4

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

于 2017-02-25T10:14:40.523 回答
2

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

感谢 Syed Rafay 的回答。

app.component.ts

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

服务器文件中

"to" => "/topics/all",
于 2019-06-28T07:41:10.143 回答
1

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

于 2018-06-02T02:40:43.377 回答
0

这是一个 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

于 2021-10-23T00:12:18.327 回答
0

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

  1. 转到firebase控制台

  2. 从侧面菜单单击“增长”

  3. 单击云消息传递

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

  5. 在通知部分,为通知标题通知文本输入一些内容

  6. 单击下一步

  7. 在目标部分单击主题

  8. 单击消息主题文本框,然后您可以看到您的主题(我没有创建名为 android 或 ios 的主题,但我可以看到这两个主题。

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

    "condition"=> "'all' in topic || 'android' in topic || 'ios' in topic",

全身

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

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

于 2020-09-24T08:02:12.233 回答
0

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

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

      subscribe();
    

重要的是写在函数的顶部!

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

    函数订阅(){

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

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

于 2021-02-23T23:06:00.093 回答
-3

您可以使用“/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!",
   }
}
于 2017-02-17T05:27:21.347 回答