此问题最初是指Google Cloud Messaging(GCM),但现在它也适用于取代GCM的新Firebase云消息传递(FCM)。
我想知道如何在GCM有效负载包含“通知”字典时计算其大小。
我一直在尝试针对Android的Google Cloud Messaging服务。文档的某些部分说您可以发送最多4KB的数据,here它说“通知消息最多可以有2kb的负载”。
做一些测试我可以发送带有4KB数据的“数据”有效负载的消息,服务器按预期接受它们而没有错误。
但是,使用“通知”有效负载我发现我可以发送超过2KB数据的消息,并且服务器没有返回错误。我预计这样的消息会太大了。
我发现“通知”有效负载与“数据”有效负载共享允许的4KB,但不是以相同的方式。在“数据”有效负载中,您可以通过添加键和值的大小来计算大小。 “通知”有效负载占用的空间大于密钥的大小和它包含的值。
如果有效载荷包含“通知”字典,我如何预先计算有效载荷的大小?
答案 0 :(得分:16)
我尝试了新的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(除了主题消息之外,我没有测试过。)
答案 1 :(得分:2)
对于下游消息传递,GCM提供两种类型的有效负载:通知和数据。通知是更轻量级的选项,具有2KB限制和一组预定义的用户可见键。数据有效负载允许开发人员发送最多4KB的自定义键/值对。通知消息可以包含可选的数据有效负载,当用户单击通知时会将其传递。
通知 - GCM会代表客户端应用自动向最终用户设备显示消息。通知具有一组预定义的用户可见键。设置通知负载。可能有可选的数据负载。总是可折叠的。
数据 - 客户端应用负责处理数据消息。数据消息只有自定义键/值对。仅设置数据有效负载。可以是可折叠的,也可以是不可折叠的。
答案 2 :(得分:1)
这可能不是您明确要求的内容,但最好不要在GCM消息中使用大量的有效负载数据。
将您的有效负载存储在数据库中,并通过Web-API使其可用。现在发送一个GCM-Message,它只包含该数据库条目的ID。现在,您的应用可以独立于GCM请求有效负载,并且您不限于此大小。
还有另一个优势:Google不会知道您通过GCM发送的内容。
如果您不需要长时间存储有效负载,您也可以使用Redis或类似的东西在有限的时间内存储该有效负载。
答案 3 :(得分:0)
我还体验到有效载荷大小仅接近4 kb。
当我试图发送一个7kb大小的有效载荷时,我向我展示了一个错误的响应,说消息太大了..
因此,您可以解析响应代码并验证Google服务器是否接受了有效负载。
答案 4 :(得分:0)
您可以使用将String数据转换为字节的传统方法。您以JSON形式获得的通知包含键/值对:
{
"to" : "APA91bHun4MxP5egoKMwt2KZFBaFUH-1RYqx...",
"notification" : {
"body" : "great match!",
"title" : "Portugal vs. Denmark"
}
}
根据Google文档:
现在使用以下方法计算数据大小:
String mydata = "value from JSON";
byte[] mybyte = mydata.getBytes("UTF-8");
int bytes = mybyte.length;
确保指定String的编码,因为不同的编码可能占用相同String的不同字节数。在上面的示例中,UTF-8用作编码。
要将字节转换为kB,只需除以1024.有关详细信息,请参阅this。
答案 5 :(得分:0)
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"
}
}
对于上述有效载荷,
总长度=(通知有效负载+数据有效负载)的长度
数据有效负载的长度= [键的长度+值的长度] = [尼克+身体+房间]的字节长度+ [Mario测试+匹配+葡萄牙VSDenmark]的字节长度= 12 + 39 = 51 < / p>
要计算通知有效负载, 每个密钥必须带有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.
希望这能回答您的问题。