17

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

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

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

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

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

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

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

4

6 回答 6

25

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

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

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

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

现在,阅读 FCM 的最新文档,我发现消息类型的文档说:

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

另一方面,“MessageTooBig”错误的描述说:

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

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

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

于 2017-05-24T13:51:29.240 回答
4

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"
   }
}

对于上述有效载荷,

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

数据有效负载长度 = [键长度 + 值长度] = [尼克 + 正文 + 房间] 的字节长度 + [马里奥测试 + 伟大匹配 + 葡萄牙VS丹麦] 的字节长度 = 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.                        

希望这能回答你的问题。

于 2019-06-19T12:47:54.013 回答
2

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

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

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

于 2017-02-20T07:59:58.037 回答
1

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

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

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

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

于 2015-07-07T18:49:16.260 回答
0

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

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

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

于 2015-07-07T18:39:36.993 回答
0

您可以使用将字符串数据转换为字节的常规方法。您以 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。有关更多详细信息,您可以参考

于 2015-07-09T23:52:18.553 回答