【问题标题】:Size of notification payload in GCM/FCMGCM/FCM 中通知负载的大小
【发布时间】:2015-09-24 16:24:18
【问题描述】:

这个问题最初是指 Google Cloud Messaging (GCM),但现在它也适用于取代 GCM 的新 Firebase Cloud Messaging (FCM)。

我想知道当 GCM 有效负载包含“通知”字典时如何计算其大小。

我一直在尝试适用于 Android 的 Google Cloud Messaging 服务。文档的某些部分说您最多可以发送 4KB 的数据,here 它说“通知消息最多可以有 2kb 的有效负载”。

做一些测试,我可以发送带有 4KB 数据的“数据”有效负载的消息,并且服务器按预期接受它们而没有错误。

但是,使用“通知”有效负载,我发现我可以发送包含超过 2KB 数据的消息,并且服务器没有返回错误。我预计这样的消息会太大。

我发现“通知”有效负载与“数据”有效负载共享允许的 4KB,但方式不同。在“数据”有效负载中,您可以通过添加键和值的大小来计算大小。 “通知”负载占用的空间超过了它所包含的键和值的大小。

当载荷包含“通知”字典时,如何提前计算载荷的大小?

【问题讨论】:

  • 这不是问题...
  • @Nilesh 我的问题更多是关于通知有效负载,它具有预定义的键并增加了整个有效负载的大小,并且似乎比包含的键和值的大小占用更多空间。
  • 您介意我更新您的问题以参考最新的 Firebase 云消息传递 (FCM) 吗? (因为 FCM 是 GCM 的新版本)。我正在为 FCM 研究这个问题,所以我可以在完成后发布答案。我不想为 FCM 发布新问题。谢谢。
  • @Eran 当然,没问题,随时更新。

标签: android google-cloud-messaging firebase-cloud-messaging


【解决方案1】:

我对较新的 FCM 服务的有效负载大小进行了试验。

对于包含“数据”字典但不包含“通知”字典的消息,我设法发送了最多 4096 个字符(计算所有键和值的长度)。

对于包含“通知”字典但没有“数据”字典的消息,以及同时包含“通知”字典和“数据”字典的消息,我设法发送了最多 4062 个字符。我不知道剩下的 34 个字符是如何计算的。

这意味着将“通知”负载限制为 2K 的文档不正确。您可以发送接近 4K 的内容。

现在,阅读 FCM 的最新文档,我发现the documentation of Message types 说:

通知消息包含一组预定义的用户可见键。相比之下,数据消息仅包含用户定义的自定义键值对。通知消息可以包含可选的数据负载。 两种消息类型的最大有效负载为 4KB,但从 Firebase 控制台发送消息时除外,该控制台强制限制为 1024 个字符。

另一方面,the description of the "MessageTooBig" error 说:

检查消息中包含的有效负载数据的总大小是否超过 FCM 限制:大多数消息为 4096 字节,或主题消息为 2048 字节。这包括键和值。

我测试的消息不是主题消息,所以根据两个引号,它们应该不限于2K。

因此,根据当前文档,有效负载限制为 4K(主题消息可能例外,我没有测试)。

【讨论】:

  • 如果我有一个大于 4kB 的字符串有效负载,有什么建议可以做吗?
【解决方案2】:

FCM 为通知负载中的每个键添加前缀 gcm.notification.

以下负载的示例计算:

  "to":"cgOtBDOGIEc:APA91bGrjdPtrnGr0sIl4c66Z3Xp-JTzUasIN5TzWy7DtNUf-BlGvF64iNOXFN68zFC6oTYHJbP6eQgzIZICcsmIUG-NP5cIXf8EyPNiIAvOFU27XDKFbI2vowMjsNmZQdmh",


  "notification":{
    "title":"Testing title from postman!",
    "body":"Testing body from postman!",
    "sound":"default",
    "tickerText":"This is ticker text"
  },
  "data" : {
     "Nick" : "Mario Test",
     "body" : "great match!",
     "Room" : "PortugalVSDenmark"
   }
}

对于上述有效载荷,

总长度 =(通知负载 + 数据负载)的长度

数据负载长度 = [键长度 + 值长度] = [ Nick + body + Room ] 的字节长度 + [Mario Test + Great match + PortugalVSDenmark 的字节长度] = 12 + 39 = 51

用于计算通知负载, 每个键都必须以 gcm.notification 为前缀。

对于通知负载的每个键,firebase 在内部添加 gcm.notification。作为前缀,并考虑这个前缀计算长度。

Length of Notification Payload  =  [ no.of keys * length of (gcm.notification.)  +  length of keys + length of values ] 

                                 = 4*17 + length of bytes of [ title + body + sound + tickerText ] + length of bytes of [ Testing title from postman! + Testing body from postman! + default + This is ticker text ]

                                                   = 68 + 24 +79

                                                   =  171 bytes

Total length of the payload = 51 + 171 =  222 bytes.                        

希望这能回答你的问题。

【讨论】:

    【解决方案3】:

    对于下游消息传递,GCM 提供两种类型的有效负载:通知和数据。通知是更轻量级的选项,具有 2KB 的限制和一组预定义的用户可见键。数据有效负载允许开发人员发送多达 4KB 的自定义键/值对。通知消息可以包含一个可选的数据有效负载,当用户单击通知时发送该有效负载。

    通知- GCM 代表客户端应用程序自动向最终用户设备显示消息。通知具有一组预定义的用户可见键。设置通知负载。可能有可选的数据负载。始终可折叠。

    数据- 客户端应用负责处理数据消息。数据消息只有自定义键/值对。仅设置数据有效负载。可以是可折叠的或不可折叠的。

    【讨论】:

    • 我们可以发送两种类型的有效载荷吗?
    【解决方案4】:

    这可能不是您明确要求的,但最好不要在您的 GCM 消息中使用大量有效负载数据。

    将您的有效负载存储在数据库中,并通过 Web-API 使其可用。现在发送一个 GCM 消息,它只包含该数据库条目的 ID。现在您的应用可以独立于 GCM 请求有效负载,并且您不受大小的限制。

    还有另一个优势:Google 不会知道您通过 GCM 发送的内容。

    如果您不需要长时间存储有效负载,您还可以使用 Redis 或类似的东西在有限的时间内存储该有效负载。

    【讨论】:

      【解决方案5】:

      我还对有效负载大小进行了实验,其大小仅接近 4 kb。

      当我尝试发送大小为 7kb 的有效负载时,我向我显示了一个错误,提示消息太大..

      因此,您可以解析响应代码并验证有效负载是否被谷歌服务器接受。

      【讨论】:

        【解决方案6】:

        您可以使用传统的方法将字符串数据转换为字节。您以 JSON 形式收到的通知包含键/值对:

        {
          "to" : "APA91bHun4MxP5egoKMwt2KZFBaFUH-1RYqx...",
          "notification" : {
            "body" : "great match!",
            "title" : "Portugal vs. Denmark"
          }
        }
        

        根据谷歌文档:

        现在使用以下方法计算数据大小:

        String mydata = "value from JSON";
        byte[] mybyte = mydata.getBytes("UTF-8");
        int bytes = mybyte.length;
        

        请务必指定字符串的编码,因为不同的编码可能会占用相同字符串的不同字节数。在上面的例子中,使用了 UTF-8 作为编码。

        要将字节转换为kB,只需除以1024即可。更多详细信息可以参考this

        【讨论】:

          猜你喜欢
          • 2020-04-20
          • 2017-08-22
          • 2017-05-22
          • 2016-09-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-09-21
          • 2019-08-26
          相关资源
          最近更新 更多