Google is committed to advancing racial equity for Black communities. See how.
Эта страница была переведа с помощью Cloud Translation API.
Switch to English

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

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

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

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

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

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

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

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

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

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

SDK Firebase Admin для FCM

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

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

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

Чтобы настроить 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. Дополнительные сведения о параметрах заголовка и тела см. В разделе Создание запросов на отправку сервера приложений.

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

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

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

В дополнение к обычным сообщениям 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":"SomeInvalidRegistrationId",
    "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 .

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

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

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

Например:

<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 необходимо закрыть соединение для балансировки нагрузки. Перед закрытием соединения FCM отправляет сообщение CONNECTION_DRAINING чтобы указать, что соединение разряжается и скоро будет закрыто. «Осушение» означает отключение потока сообщений, поступающих в соединение, но позволяющее продолжить работу всего, что уже находится в конвейере. Когда вы получаете сообщение CONNECTION_DRAINING , вы должны немедленно начать отправку сообщений в другое соединение FCM, открывая при необходимости новое соединение. Однако вы должны оставить исходное соединение открытым и продолжать получать сообщения, которые могут приходить через соединение (и подтверждать их) - 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:

Рисунок 1. Поток сообщений / подтверждений.

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

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