この質問は、元はGoogleクラウドメッセージング(GCM)に関するものでしたが、現在はGCMに代わる新しいFirebase Cloud Messaging(FCM)にも当てはまります。
「通知」辞書を含むGCMペイロードのサイズを計算する方法を教えてください。
Android向けのGoogleクラウドメッセージングサービスを試しています。ドキュメントの一部には、最大4KBのデータを送信できると記載されています ここ は、「通知メッセージは最大2kbのペイロードを持つことができる」と述べています。
いくつかのテストを行うと、4KBのデータで満たされた「データ」ペイロードを含むメッセージを送信でき、サーバーは期待どおりにエラーなしでそれらを受け入れました。
しかし、「通知」ペイロードを使用すると、2KBを超えるデータを含むメッセージを送信でき、サーバーはエラーを返しませんでした。そのようなメッセージは大きすぎると思いました。
「通知」ペイロードは許可された4KBを「データ」ペイロードと共有しますが、同じ方法ではないことがわかりました。 「データ」ペイロードでは、キーと値のサイズを追加してサイズを計算できます。 「通知」ペイロードは、含まれるキーと値のサイズよりも多くのスペースを使用します。
「通知」ディクショナリが含まれているペイロードのサイズを事前に計算するにはどうすればよいですか?
新しいFCMサービスのペイロードサイズを実験しました。
「データ」ディクショナリを含み、「通知」ディクショナリを含まないメッセージの場合、最大4096文字(すべてのキーと値の長さをカウント)まで正確に送信できました。
「通知」辞書を含み、「データ」辞書を含まないメッセージ、および「通知」辞書と「データ」辞書の両方を含むメッセージの場合、最大4062文字まで送信できました。残りの34文字がどのようにカウントされるのかわかりませんでした。
これは、「通知」ペイロードを2Kに制限するドキュメントが正しくないことを意味します。 4K近くまで送れます。
現在、FCMの最新のドキュメントを読んでいると、 メッセージタイプのドキュメント が次のように言うことがわかりました。
通知メッセージには、ユーザーに表示される事前定義されたキーのセットが含まれています。対照的に、データメッセージには、ユーザー定義のカスタムKey-Valueペアのみが含まれます。通知メッセージには、オプションのデータペイロードを含めることができます。 両方のメッセージタイプの最大ペイロードは4KBですが、Firebaseコンソールからメッセージを送信する場合は、1024文字の制限が適用されます。
一方、 「MessageTooBig」エラーの説明 は次のように述べています。
メッセージに含まれるペイロードデータの合計サイズがFCMの制限を超えていないことを確認します。ほとんどのメッセージでは4096バイト、またはトピックへのメッセージの場合は2048バイト。これには、キーと値の両方が含まれます。
私がテストしたメッセージはトピックへのメッセージではなかったので、両方の引用によれば、それらは2Kに限定されるべきではありません。
したがって、現在のドキュメントによると、ペイロードの制限は4Kです(トピックへのメッセージの例外を除いて、私はテストしていません)。
ダウンストリームメッセージングの場合、GCMは2種類のペイロード(通知とデータ)を提供します。通知はより軽量なオプションであり、2KBの制限とユーザーに表示されるキーの事前定義されたセットがあります。データペイロードにより、開発者は最大4KBのカスタムキー/値ペアを送信できます。通知メッセージには、ユーザーが通知をクリックしたときに配信されるオプションのデータペイロードを含めることができます。
通知-GCMは、クライアントアプリに代わってエンドユーザーのデバイスにメッセージを自動的に表示します。通知には、ユーザーに表示される事前定義されたキーのセットがあります。通知ペイロードを設定します。オプションのデータペイロードを含めることができます。常に折りたたみ可能。
Data-クライアントアプリはデータメッセージの処理を担当します。データメッセージには、カスタムのキーと値のペアしかありません。データペイロードのみを設定します。折りたたみ可能または折りたたみ不可のいずれかです。
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"
}
}
上記のペイロードの場合、
全長=(通知ペイロード+データペイロード)の長さ
データペイロードの長さ= [キーの長さ+値の長さ] = [ニックネーム+本体+部屋]のバイト長+ [マリオテスト+優れた一致+ポルトガルVSDenmark]のバイト長= 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.
これがあなたの質問に答えることを願っています。
これは、明示的に要求したものではない可能性がありますが、GCMメッセージ内でその大量のペイロードデータを使用しない方がよいでしょう。
ペイロードをデータベース内に保存し、Web-APIを介して利用できるようにします。次に、そのデータベースエントリのIDのみを保持するGCMメッセージを送信します。これで、アプリはGCMとは無関係にペイロードをリクエストでき、サイズに制限されません。
別の利点もあります。GoogleはGCM経由で何を送信するかを認識しません。
ペイロードを長期間保存する必要がない場合は、Redisなどを使用して、そのペイロードを一定期間保存することもできます。
また、ペイロードサイズを約4 kbに近づけました。
サイズが7 kbのペイロードを送信しようとしたときに、メッセージが大きすぎるというエラーメッセージが表示されました。
したがって、応答コードを解析して、ペイロードがGoogleサーバーに受け入れられたかどうかを確認できます。
文字列データをバイトに変換する従来の方法を使用できます。次のようなキーと値のペアを含む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;
文字列のエンコードは、同じ文字列でもバイト数が異なる場合があるため、必ず指定してください。上記の例では、エンコーディングとしてUTF-8が使用されています。
バイトをkBに変換するには、1024で除算します。詳細については、 this を参照してください。