Catch up on everthing we announced at this year's Firebase Summit. Learn more

Ваша серверная среда и FCM

Серверная часть Firebase Cloud Messaging состоит из двух компонентов:

  • FCM бэкенд предоставлена Google.
  • Ваш сервер приложений или другая среда доверенного сервера , где ваш сервер работает логика, такие как облачные функции для Firebase или других облачных среды под управлением Google.

Ваш сервер приложений или среда доверенного сервера отправляет запросы сообщений в бэкэнд FCM, который затем направляет сообщения в клиентские приложения, работающие на устройствах пользователей.

Требования к доверенной серверной среде

Ваша среда сервера приложений должна соответствовать следующим критериям:

  • Возможность отправлять правильно отформатированные запросы сообщений на серверную часть FCM.
  • Способен обрабатывать запросы и отправить их с помощью экспоненциальной обратно-офф.
  • Возможность безопасного хранения учетных данных для авторизации сервера и токенов регистрации клиентов.
  • Для протокола XMPP (если он используется) сервер должен иметь возможность генерировать идентификаторы сообщений, чтобы однозначно идентифицировать каждое отправляемое им сообщение (серверная часть HTTP FCM генерирует идентификаторы сообщений и возвращает их в ответе). Идентификаторы сообщений XMPP должны быть уникальными для каждого идентификатора отправителя.

Выбор варианта сервера

Вы должны решить , на пути , чтобы взаимодействовать с серверами ТСМ: либо с помощью Firebase Admin SDK или необработанные протоколы. Из-за поддержки популярных языков программирования и удобных методов обработки аутентификации и авторизации рекомендуется использовать Firebase Admin SDK.

Варианты взаимодействия с серверами FCM включают следующее:
  • Firebase Admin SDK, который поддерживает узел , Java , Python , C # , и Go .
  • FCM HTTP v1 API , который является наиболее актуальной из вариантов протокола, более безопасной авторизации и гибкими возможностями кросс-платформенного обмена сообщениями (The Firebase Администратор SDK основан на этом протоколе и предоставляет все свои преимущества , присущие).
  • Наследство HTTP протокол.
  • XMPP протокол сервера. Обратите внимание: если вы хотите использовать восходящий обмен сообщениями из клиентских приложений, вы должны использовать XMPP.

Firebase Admin SDK для FCM

API Admin FCM обрабатывает аутентификацию с помощью серверной части и упрощает отправку сообщений и управление подписками на темы. С помощью Firebase Admin SDK вы можете:

  • Отправлять сообщения на отдельные устройства
  • Отправляйте сообщения темам и условиям, которые соответствуют одной или нескольким темам.
  • Подписка и отмена подписки устройств на темы и от них
  • Создавайте полезные нагрузки сообщений, адаптированные к различным целевым платформам

Пакет Admin Node.js SDK предоставляет методы для отправки сообщений группам устройств.

Для того, чтобы настроить Firebase Admin SDK см Добавить Firebase Admin SDK для вашего сервера . Если у вас уже есть проект Firebase, начните с Добавьте SDK . Затем, после установки Firebase Admin SDK, вы можете начать писать логику для запросов сборки посыла .

Протоколы сервера FCM

В настоящее время FCM предоставляет следующие необработанные серверные протоколы:

Сервер приложений может использовать эти протоколы по отдельности или в тандеме. Поскольку это самый современный и самый гибкий для отправки сообщений на несколько платформ, FCM HTTP v1 API рекомендуется везде, где это возможно. Если ваши требования включают восходящий обмен сообщениями с устройств на сервер, вам необходимо реализовать протокол XMPP.

Обмен сообщениями XMPP отличается от обмена сообщениями HTTP следующим образом:

  • Сообщения в восходящем / нисходящем направлении
    • HTTP: только нисходящий поток, от облака к устройству.
    • XMPP: восходящий и нисходящий поток (от устройства к облаку, от облака к устройству).
  • Обмен сообщениями (синхронный или асинхронный)
    • HTTP: синхронный. Серверы приложений отправляют сообщения в виде запросов HTTP POST и ждут ответа. Этот механизм является синхронным и блокирует отправителя от отправки другого сообщения до тех пор, пока не будет получен ответ.
    • XMPP: асинхронный. Серверы приложений отправляют / получают сообщения на / со всех своих устройств на полной скорости по постоянным соединениям XMPP. Сервер соединений XMPP отправляет уведомления о подтверждении или сбое (в форме специальных сообщений XMPP с кодировкой ACK и NACK в формате JSON) асинхронно.
  • JSON
    • HTTP: сообщения JSON, отправленные как HTTP POST.
    • XMPP: сообщения JSON, инкапсулированные в сообщениях XMPP.
  • Простой текст
    • HTTP: сообщения в формате обычного текста, отправляемые как HTTP POST.
    • XMPP: не поддерживается.
  • Многоадресная отправка в нисходящем направлении на несколько токенов регистрации.
    • HTTP: поддерживается в формате сообщения JSON.
    • XMPP: не поддерживается.

Реализация протокола HTTP-сервера

Чтобы отправить сообщение, сервер приложения выдает запрос POST с заголовком HTTP и телом HTTP, состоящим из пар ключей JSON. Для получения дополнительной информации о заголовке и теле вариантов см Строительные Отправлять запросы App сервера

Реализация протокола сервера XMPP

Полезная нагрузка JSON для сообщений FCM аналогична протоколу HTTP, за следующими исключениями:

  • Нет поддержки для нескольких получателей.
  • FCM добавляет поле message_id , который необходим. Этот идентификатор однозначно идентифицирует сообщение в XMPP-соединении. ACK или NACK от ТСМ использует message_id для идентификации сообщения , отправленные с серверов приложений для ТСМ. Поэтому очень важно , чтобы это message_id не только быть уникальным (за Sender ID ), но всегда присутствует.
  • XMPP использует ключ сервера для авторизации постоянного подключения к FCM. См Авторизоваться Отправить запросы для получения дополнительной информации.

В дополнение к обычным сообщениям ТСМ, управляющие сообщения посылаются, указывает message_type поля в объекте JSON. Значение может быть либо «ack», либо «nack», либо «control» (см. Форматы ниже). Любое сообщение FCM с неизвестным message_type могут быть проигнорированы вашим сервером.

Для каждого сообщения устройства, которое ваш сервер приложений получает от FCM, он должен отправить сообщение ACK. Ему никогда не нужно отправлять сообщение NACK. Если вы не отправляете ACK для сообщения, FCM повторно отправляет его в следующий раз, когда будет установлено новое соединение XMPP, если только сообщение не истечет первым.

FCM также отправляет ACK или NACK для каждого сообщения от сервера к устройству. Если вы не получили ни того, ни другого, это означает, что TCP-соединение было закрыто в середине операции, и вашему серверу необходимо повторно отправить сообщения. См управления потоком для деталей.

См Код протокола для получения списка всех параметров сообщения.

Формат запроса

Сообщение с полезной нагрузкой - уведомление

Вот параграфа XMPP для уведомляющего сообщения:

<message id="">
  <gcm xmlns="google:mobile:data">
  {
     "to":"REGISTRATION_ID",  // "to" replaces "registration_ids"
     "notification": {
        "title": "Portugal vs. Denmark”,
        "body”: "5 to 1”
      },
      "time_to_live":"600"
  }
  </gcm>
</message>

Сообщение с полезной нагрузкой - сообщение с данными

Вот фрагмент XMPP, содержащий сообщение JSON от сервера приложения к FCM:

<message id="">
  <gcm xmlns="google:mobile:data">
  {
      "to":"REGISTRATION_ID",  // "to" replaces "registration_ids"
      "message_id":"m-1366082849205" // new required field
      "data":
      {
          "hello":"world",
      }
      "time_to_live":"600",
  }
  </gcm>
</message>

Формат ответа

Ответ FCM может иметь три возможных формы. Первое - это обычное сообщение «подтверждение». Но когда ответ содержит ошибку, сообщение может принимать две разные формы, описанные ниже.

Сообщение ACK

Вот раздел XMPP, содержащий сообщение ACK / NACK от FCM серверу приложений:

<message id="">
  <gcm xmlns="google:mobile:data">
  {
      "from":"REGID",
      "message_id":"m-1366082849205"
      "message_type":"ack"
  }
  </gcm>
</message>

Сообщение NACK

NACK ошибка является регулярным XMPP сообщения , в котором message_type сообщение о состоянии «NACK». Сообщение NACK содержит:

  • Код ошибки NACK.
  • Описание ошибки NACK.

Ниже приведены некоторые примеры.

Плохая регистрация:

<message>
  <gcm xmlns="google:mobile:data">
  {
    "message_type":"nack",
    "message_id":"msgId1",
    "from":"SomeInvalidRegistrationToken",
    "error":"BAD_REGISTRATION",
    "error_description":"Invalid token on 'to' field: SomeInvalidRegistrationId"
  }
  </gcm>
</message>

Неверный JSON:

<message>
 <gcm xmlns="google:mobile:data">
 {
   "message_type":"nack",
   "message_id":"msgId1",
   "from":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
   "error":"INVALID_JSON",
   "error_description":"InvalidJson: JSON_TYPE_ERROR : Field \"time_to_live\" must be a JSON java.lang.Number: abc"
 }
 </gcm>
</message>

Превышена частота сообщений устройства:

<message id="...">
  <gcm xmlns="google:mobile:data">
  {
    "message_type":"nack",
    "message_id":"msgId1",
    "from":"REGID",
    "error":"DEVICE_MESSAGE_RATE_EXCEEDED",
    "error_description":"Downstream message rate exceeded for this registration id"
  }
  </gcm>
</message>

Смотрите справочный сервер для полного списка кодов ошибок NACK. Если не указано иное, повторять попытку сообщения NACKed не следует. Неожиданные коды ошибок NACK должны быть обработаны так же , как INTERNAL_SERVER_ERROR .

Ошибка строфы

В некоторых случаях вы также можете получить ошибку строфы. Ошибка строфы содержит:

  • Код ошибки строфы.
  • Описание ошибки строфы (свободный текст).

Например:

<message id="3" type="error" to="123456789@fcm.googleapis.com/ABC">
  <gcm xmlns="google:mobile:data">
     {"random": "text"}
  </gcm>
  <error code="400" type="modify">
    <bad-request xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
    <text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">
      InvalidJson: JSON_PARSING_ERROR : Missing Required Field: message_id\n
    </text>
  </error>
</message>

Контрольные сообщения

Периодически FCM необходимо закрыть соединение для балансировки нагрузки. Перед тем , как закрыть соединение, ТСМ посылает CONNECTION_DRAINING сообщение , чтобы указать , что соединение истощается и будет закрыто в ближайшее время . «Осушение» означает отключение потока сообщений, поступающих в соединение, но позволяющее продолжить работу всего, что уже находится в конвейере. Когда вы получите CONNECTION_DRAINING сообщение, вы должны немедленно начать отправку сообщений в связи с другим ТСМ, открывая новое соединение , если это необходимо. Однако вы должны оставить исходное соединение открытым и продолжать получать сообщения, которые могут приходить через соединение (и подтверждать их) - FCM обрабатывает инициирование закрытия соединения, когда оно готово.

CONNECTION_DRAINING сообщение выглядит следующим образом :

<message>
  <data:gcm xmlns:data="google:mobile:data">
  {
    "message_type":"control"
    "control_type":"CONNECTION_DRAINING"
  }
  </data:gcm>
</message>

CONNECTION_DRAINING в настоящее время только control_type поддерживается.

Управление потоком

Каждое сообщение, отправленное в FCM, получает ответ ACK или NACK. Сообщения, на которые не был получен ни один из этих ответов, считаются ожидающими. Если количество ожидающих сообщений достигает 100, сервер приложений должен прекратить отправку новых сообщений и дождаться, пока FCM подтвердит некоторые из существующих ожидающих сообщений, как показано на рисунке 1:

Подробная схема потока управления между FCM и сервером приложений

Рисунок 1. Сообщение / извед течь.

И наоборот, чтобы избежать перегрузки сервера приложений, FCM прекращает отправку, если имеется слишком много неподтвержденных сообщений. Таким образом, сервер приложений должен как можно скорее «подтверждать» восходящие сообщения, полученные от клиентского приложения через FCM, чтобы поддерживать постоянный поток входящих сообщений. Вышеупомянутый лимит ожидающих сообщений не применяется к этим ACK. Даже если количество ожидающих сообщений достигает 100, сервер приложений должен продолжать отправлять ACK для сообщений, полученных от FCM, чтобы избежать блокировки доставки новых сообщений восходящего потока.

ACK действительны только в контексте одного соединения. Если соединение закрывается до того, как сообщение может быть подтверждено, сервер приложений должен дождаться, пока FCM повторно отправит восходящее сообщение, прежде чем снова подтвердить его. Точно так же все ожидающие сообщения, для которых ACK / NACK не был получен от FCM до закрытия соединения, должны быть отправлены снова.