Размер полезной нагрузки уведомления в GCM/FCM

Этот вопрос первоначально относился к Google Cloud Messaging (GCM), но теперь он также относится к новому Firebase Cloud Messaging (FCM), который заменяет GCM.

Я хотел бы знать, как рассчитать размер полезной нагрузки GCM, когда он содержит словарь "уведомлений".

Я пробовал службу Google Cloud Messaging для Android. В некоторых частях документации говорится, что вы можете отправить до 4 КБ данных, а здесь говорится: "Уведомление может иметь максимальную полезную нагрузку 2 КБ".

Выполняя некоторые тесты, я мог отправлять сообщения с полезной нагрузкой "data", заполненной 4 КБ данных, и сервер принимал их без ошибок, как и ожидалось.

Однако, используя полезную нагрузку "уведомление", я обнаружил, что могу отправлять сообщения с объемом данных более 2 КБ, и сервер не возвращает ошибку. Я ожидал, что такие сообщения будут слишком большими.

Я обнаружил, что полезная нагрузка "уведомление" разделяет разрешенные 4 КБ с полезной нагрузкой "данные", но не так. В полезных данных "data" вы можете рассчитать размер, добавив размер ключей и значений. Полезная нагрузка "уведомление" занимает больше места, чем размер ключей и значений, которые она содержит.

Как я могу заранее рассчитать размер полезной нагрузки, если она содержит словарь уведомлений?

Ответ 1

Я экспериментировал с размерами полезной нагрузки для нового сервиса FCM.

Для сообщений, которые содержат словарь "данных" и нет словаря "уведомлений", мне удалось отправить ровно до 4096 символов (считая длины всех ключей и значений).

Для сообщений, которые содержат словарь "уведомлений" и нет словаря "данных", а также для сообщений, которые содержат словарь "уведомлений" и словарь "данных", мне удалось отправить до 4062 символов. Я не мог понять, как подсчитываются оставшиеся 34 символа.

Это означает, что документация, ограничивающая полезную нагрузку "уведомление" до 2 КБ, неверна. Вы можете отправить около 4К.

Теперь, читая современную документацию FCM, я обнаружил, что документация типов сообщений гласит:

Уведомительные сообщения содержат предопределенный набор видимых пользователю ключей. Напротив, сообщения данных содержат только ваши пользовательские пользовательские пары ключ-значение. Уведомления могут содержать необязательные данные. Максимальная полезная нагрузка для обоих типов сообщений составляет 4 КБ, за исключением случаев отправки сообщений из консоли Firebase, что обеспечивает ограничение в 1024 символа.

С другой стороны, описание ошибки "MessageTooBig" гласит:

Убедитесь, что общий размер данных полезной нагрузки, включенных в сообщение, не превышает ограничения FCM: 4096 байт для большинства сообщений или 2048 байт в случае сообщений в разделах. Это включает в себя как ключи, так и значения.

Сообщения, которые я тестировал, не были сообщениями к темам, поэтому, согласно обеим цитатам, они не должны быть ограничены 2К.

Поэтому предел полезной нагрузки в соответствии с текущей документацией составляет 4 КБ (за исключением возможных сообщений в темах, которые я не тестировал).

Ответ 2

Для обмена сообщениями по потоку, GCM предоставляет два типа полезной нагрузки: уведомление и данные. Уведомление - это более легкий вариант с ограничением 2 КБ и предопределенным набором видимых пользователем клавиш. Полезная нагрузка данных позволяет разработчикам отправлять до 4 КБ пользовательских пар ключ/значение. Сообщения уведомления могут содержать дополнительную полезную нагрузку данных, которая доставляется, когда пользователи нажимают на уведомление.

Уведомление - GCM автоматически отображает сообщение для конечных пользовательских устройств от имени клиентского приложения. Уведомления имеют предопределенный набор видимых пользователем ключей. Установите полезную нагрузку уведомления. Может иметь дополнительную полезную нагрузку данных. Всегда сжимается.

Данные. Клиентское приложение отвечает за обработку сообщений данных. В сообщениях данных есть только настраиваемые пары ключ/значение. Установите только полезную нагрузку данных. Может быть либо разборным, либо нескладным.

Ответ 3

Это может быть не то, о чем вы просили, но лучше не использовать этот большой объем полезных данных в вашем GCM-сообщении.

Сохраните свою полезную нагрузку внутри базы данных и сделайте ее доступной через веб-API. Теперь отправьте GCM-сообщение, в котором содержится только идентификатор этой записи базы данных. Теперь ваше приложение может запросить полезную нагрузку независимо от GCM, и вы не ограничены размером.

Есть еще одно преимущество: Google не будет знать, что вы отправляете через GCM.

Если вам не нужно долго хранить полезную нагрузку, вы также можете использовать Redis или что-то подобное для хранения этой полезной нагрузки в течение ограниченного времени.

Ответ 4

Я также экспериментировал с размером полезной нагрузки около около 4 килобайт.

Когда я попытался отправить полезную нагрузку размером 7kb, я показал мне erroe в ответ, который говорит, что сообщение слишком велико.

Итак, вы можете проанализировать код ответа и убедиться, что полезная нагрузка была принята серверами google или нет.

Ответ 5

Вы можете использовать обычный метод преобразования данных 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. Более подробную информацию вы можете найти .

Ответ 6

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.                        

Надеюсь, что это ответ на ваш вопрос.