GCM/FCM中通知负载的大小

18

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

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

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

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

然而,当我使用“notification”有效负载时,我发现我可以发送超过2KB的数据而服务器没有返回错误。我预计这样的消息将太大了。

我发现 “notification”有效负载与"data"有效负载共享允许的4KB,但方式不同。“data”有效负载中,您可以通过添加键和值的大小来计算大小。“notification”有效负载所占用的空间比其包含的键和值的大小更大。

当有效负载包含“notification”字典时,我该如何预先计算其大小?


请查看此链接:http://stackoverflow.com/questions/29012915/gcm-messageor-data-limit - N J
@Nilesh 我的问题更多关于通知负载,它有预定义的键并增加了整个负载的大小,似乎占用的空间比包含的键和值的大小还要大。 - jorcasso
2
你介意我更新你的问题,将其引用更为现行的 Firebase Cloud Messaging (FCM)(因为FCM是GCM的新版本)吗?我正在研究FCM的这个问题,等我完成后可以发布一个答案。我倾向于不为FCM发布一个新问题。谢谢。 - Eran
@Eran 没问题,随意更新它。 - jorcasso
@jorcasso 谢谢!已完成。 - Eran
显示剩余2条评论
6个回答

27

我对新的FCM服务尝试了负载大小。

对于包含“data”字典但不包含“notification”字典的消息,我成功发送了最多4096个字符(包括所有键和值的长度)。

对于包含“notification”字典但不包含“data”字典以及同时包含“notification”字典和“data”字典的消息,我成功发送了最多4062个字符。我无法确定剩余的34个字符如何被计算。

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

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

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

另一方面,“MessageTooBig”错误的描述中写道:

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

我测试的消息不是发送到主题的消息,因此根据上述两个引用,它们不应被限制为2K。

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


如果我有一个大于4kB的字符串负载,有什么建议可以做? - Akshay Bhat 'AB'

8

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.                        


希望这能回答你的问题。

2
对于下行消息,GCM提供两种负载类型:通知和数据。通知是更轻量级的选项,有2KB的限制和一组预定义的用户可见键。数据负载允许开发人员发送最多4KB的自定义键/值对。通知消息可以包含一个可选的数据负载,在用户点击通知时传递。 通知 - GCM代表客户端应用程序自动向终端用户设备显示消息。通知具有预定义的一组用户可见键。设置通知负载。可能具有可选的数据负载。始终可折叠。 数据 - 客户端应用程序负责处理数据消息。数据消息仅具有自定义键/值对。仅设置数据负载。可以是可折叠或不可折叠。

我们可以同时发送两种类型的有效载荷吗? - Himanshu

1
这可能不是你明确要求的,但最好不要在GCM消息中使用大量有效载荷数据。将有效载荷存储在数据库中,并通过Web-API使其可用。现在发送一个只包含该数据库条目ID的GCM消息。现在,您的应用程序可以独立于GCM请求有效载荷,而且没有大小限制。另一个优点是:Google不会知道您通过GCM发送了什么。如果您不需要长时间存储有效载荷,还可以使用Redis或类似工具来存储有效载荷,但时间有限。

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即可。有关更多详细信息,请参阅this


0

我也尝试过负载大小,大小只有约4 KB。

当我试图发送一个7KB大小的负载时,它向我显示了一个错误响应,显示消息太大。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接