【问题标题】:FCM (Firebase Cloud Messaging) Send to multiple devicesFCM(Firebase 云消息传递)发送到多个设备
【发布时间】:2017-01-25 14:45:21
【问题描述】:

我执行此代码以使用 FCM 库将通知推送到移动设备

public string PushFCMNotification(string deviceId, string message) 
    {
        string SERVER_API_KEY = "xxxxxxxxxxxxxxxxxxxxxxx";
        var SENDER_ID = "xxxxxxxxx";
        var value = message;
        WebRequest tRequest;
        tRequest = WebRequest.Create("https://fcm.googleapis.com/fcm/send");
        tRequest.Method = "post";
        tRequest.ContentType = "application/json";
        tRequest.Headers.Add(string.Format("Authorization: key={0}", SERVER_API_KEY));

        tRequest.Headers.Add(string.Format("Sender: id={0}", SENDER_ID));

        var data = new
        {
            to = deviceId,
            notification = new
            {
                body = "This is the message",
                title = "This is the title",
                icon = "myicon"
            }
        };

        var serializer = new JavaScriptSerializer();
        var json = serializer.Serialize(data);

        Byte[] byteArray = Encoding.UTF8.GetBytes(json);

        tRequest.ContentLength = byteArray.Length;

        Stream dataStream = tRequest.GetRequestStream();
        dataStream.Write(byteArray, 0, byteArray.Length);
        dataStream.Close();

        WebResponse tResponse = tRequest.GetResponse();

        dataStream = tResponse.GetResponseStream();

        StreamReader tReader = new StreamReader(dataStream);

        String sResponseFromServer = tReader.ReadToEnd();


        tReader.Close();
        dataStream.Close();
        tResponse.Close();
        return sResponseFromServer;
    }

现在,如何向多台设备发送消息, 假设字符串 deviceId 参数替换为 List devicesIDs。

你能帮忙吗

【问题讨论】:

标签: android asp.net firebase-cloud-messaging


【解决方案1】:

更新:对于 v1,似乎不再支持 registration_ids。强烈建议改用主题。 v1 仅支持documentation 中显示的参数。


只需在您的有效负载中使用registration_ids 参数而不是to。根据您的用例,您可以使用Topic Messaging 或Device Group Messaging。

主题消息传递

Firebase 云消息传递 (FCM) 主题消息传递允许您向已选择加入特定主题的多个设备发送消息。基于发布/订阅模型,主题消息支持每个应用程序的无限订阅。您可以根据需要编写主题消息,Firebase 会处理消息路由并将消息可靠地传递到正确的设备。

例如,本地天气预报应用的用户可以选择加入“恶劣天气警报”主题并接收风暴威胁指定区域的通知。体育应用程序的用户可以订阅他们最喜欢的球队的实时比赛比分的自动更新。开发者可以选择任何匹配正则表达式的主题名称:"/topics/[a-zA-Z0-9-_.~%]+"。


设备组消息

通过设备群组消息传递,应用服务器可以将单个消息发送到在属于某个群组的设备上运行的应用的多个实例。 通常,“组”是指属于单个用户的一组不同设备。组中的所有设备共享一个公共通知密钥,这是 FCM 用来将消息扇出到组中所有设备的令牌。

设备群组消息让群组中的每个应用实例都可以反映最新的消息状态。除了向下游发送消息到通知键之外,您还可以使设备能够向设备组发送上游消息。您可以将设备组消息与 XMPP 或 HTTP 连接服务器一起使用。发送到 iOS 设备时数据负载限制为 2KB,其他平台为 4KB。

notification_key 允许的最大成员数为 20。


有关更多详细信息,您可以查看Sending to Multiple Devices in FCM 文档。

【讨论】:

  • 还可以考虑使用主题,尤其是在您发送到的设备数量超过 1000 台时。
  • 可以添加For v1, it seems that registration_ids is no longer supported.的来源吗?
  • @NimitBhargava firebase.google.com/docs/reference/fcm/rest/v1/… -- registration_ids 未指定用于 v1。
【解决方案2】:

您应该创建一个主题并让用户订阅该主题。 这样,当您发送 FCM 消息时,每个订阅的用户都会收到它,但您实际上想要记录他们的 ID 以用于特殊目的。

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

查看此链接:https://firebase.google.com/docs/cloud-messaging/android/topic-messaging

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

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

【讨论】:

  • 这是我认为的最佳答案。但我的解决方案很容易从客户端实现。你太棒了。
  • 这总是返回 Error=InvalidRegistration。无需注册令牌。对吗?
  • 您是否忘记定义 API 密钥?
  • 如果用户退出,设备应该取消订阅所有主题,并根据新的认证用户重新订阅?
  • 这适用于单个主题,适用于他们在 firebase 文档中提到的多个主题:主题中的“TopicA”||主题中的“主题 B”||主题中的“主题 C”。有没有其他方法可以一次将多个主题发送到端点。
【解决方案3】:

请按照以下步骤操作。

public String addNotificationKey(
    String senderId, String userEmail, String registrationId, String idToken)
    throws IOException, JSONException {
URL url = new URL("https://android.googleapis.com/gcm/googlenotification");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setDoOutput(true);

// HTTP request header
con.setRequestProperty("project_id", senderId);
con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("Accept", "application/json");
con.setRequestMethod("POST");
con.connect();

// HTTP request
JSONObject data = new JSONObject();
data.put("operation", "add");
data.put("notification_key_name", userEmail);
data.put("registration_ids", new JSONArray(Arrays.asList(registrationId)));
data.put("id_token", idToken);

OutputStream os = con.getOutputStream();
os.write(data.toString().getBytes("UTF-8"));
os.close();

// Read the response into a string
InputStream is = con.getInputStream();
String responseString = new Scanner(is, "UTF-8").useDelimiter("\\A").next();
is.close();

// Parse the JSON string and return the notification key
JSONObject response = new JSONObject(responseString);
return response.getString("notification_key");

}

我希望上面的代码能帮助你在多个设备上发送推送。 更多详情请参考此链接https://firebase.google.com/docs/cloud-messaging/android/device-group

***注意:请务必通过上述链接阅读关于创建/删除组。

【讨论】:

    【解决方案4】:

    FCM DOcument中提到的一个注意事项如下,

    注意:任何使用设备群组消息传递的应用都必须继续使用旧版 API 来管理设备群组(创建、更新等)。 HTTP v1 可以向设备组发送消息,但不支持管理。

    https://firebase.google.com/docs/cloud-messaging/migrate-v1

    此外,Admin SDK 使用 Batch HttpPostrequest 使消费者更容易,因此如果您想要设备组消息传递,您仍然可以使用 New V1 FCM API,但使用 FCM Admin SDK。

    这里是来自 Admin SDK 的代码,可以为您完成这项工作。

    类名:FirebaseMessagingClientImpl

        for (Message message : messages) {
          // Using a separate request factory without authorization is faster for large batches.
          // A simple performance test showed a 400-500ms speed up for batches of 1000 messages.
          HttpRequest request = childRequestFactory.buildPostRequest(
              sendUrl,
              new JsonHttpContent(jsonFactory, message.wrapForTransport(dryRun)));
          request.setParser(jsonParser);
          setCommonFcmHeaders(request.getHeaders());
          batch.queue(
              request, MessagingServiceResponse.class, MessagingServiceErrorResponse.class, callback);
        }

    【讨论】:

      猜你喜欢
      • 2017-03-10
      • 1970-01-01
      • 2020-10-15
      • 1970-01-01
      • 2022-01-09
      • 2021-01-19
      • 1970-01-01
      相关资源
      最近更新 更多