Разрешить отправку запросов

Запросы, отправленные в FCM с вашего сервера приложений или доверенной среды, должны быть авторизованы. Обратите внимание на эти важные различия между устаревшим устаревшим HTTP API и авторизацией API HTTP v1:

  • API FCM HTTP v1 авторизует запросы с помощью недолговечного токена доступа OAuth 2.0. Чтобы создать этот токен, вы можете использовать учетные данные приложения Google по умолчанию (в средах серверов Google) и/или вручную получить необходимые учетные данные из файла закрытого ключа JSON, созданного для учетной записи службы. Если вы используете Firebase Admin SDK для отправки сообщений, библиотека обрабатывает токен за вас.
  • Устаревшие устаревшие протоколы могут использовать только долгоживущие ключи API, полученные из консоли Firebase .

Разрешить запросы на отправку HTTP v1

В зависимости от деталей вашей серверной среды используйте комбинацию этих стратегий для авторизации запросов сервера к сервисам Firebase:

  • Учетные данные приложения Google по умолчанию (ADC)
  • JSON-файл сервисного аккаунта
  • Недолговечный токен доступа OAuth 2.0, полученный из учетной записи службы.

Если ваше приложение работает на Compute Engine , Google Kubernetes Engine , App Engine или облачных функциях (включая Cloud Functions for Firebase ), используйте учетные данные приложения по умолчанию (ADC). ADC использует существующую учетную запись службы по умолчанию для получения учетных данных для авторизации запросов, а ADC обеспечивает гибкое локальное тестирование с помощью переменной среды GOOGLE_APPLICATION_CREDENTIALS . Для максимально полной автоматизации процесса авторизации используйте ADC вместе с серверными библиотеками Admin SDK.

Если ваше приложение работает в серверной среде, отличной от Google , вам необходимо скачать JSON-файл сервисного аккаунта из вашего проекта Firebase. Если у вас есть доступ к файловой системе, содержащей файл закрытого ключа, вы можете использовать переменную среды GOOGLE_APPLICATION_CREDENTIALS для авторизации запросов с этими учетными данными, полученными вручную. Если у вас нет такого доступа к файлу, вы должны ссылаться на файл учетной записи службы в своем коде, что следует делать с особой осторожностью из-за риска раскрытия ваших учетных данных.

Предоставьте учетные данные с помощью ADC

Учетные данные приложения Google по умолчанию (ADC) проверяют ваши учетные данные в следующем порядке:

  1. ADC проверяет, установлена ​​ли переменная среды GOOGLE_APPLICATION_CREDENTIALS . Если переменная установлена, ADC использует файл учетной записи службы, на который указывает переменная.

  2. Если переменная среды не установлена, ADC использует учетную запись службы по умолчанию, которую Compute Engine , Google Kubernetes Engine , App Engine и Cloud Functions предоставляют приложениям, работающим в этих службах.

  3. Если ADC не может использовать ни один из указанных выше учетных данных, система выдает ошибку.

Следующий пример кода Admin SDK иллюстрирует эту стратегию. В примере явно не указаны учетные данные приложения. Однако ADC может неявно находить учетные данные, если установлена ​​переменная среды или пока приложение работает в Compute Engine , Google Kubernetes Engine , App Engine или Cloud Functions.

Node.js

admin.initializeApp({
  credential: admin.credential.applicationDefault(),
});

Ява

FirebaseOptions options = FirebaseOptions.builder()
    .setCredentials(GoogleCredentials.getApplicationDefault())
    .setDatabaseUrl("https://<DATABASE_NAME>.firebaseio.com/")
    .build();

FirebaseApp.initializeApp(options);

Питон

default_app = firebase_admin.initialize_app()

Идти

app, err := firebase.NewApp(context.Background(), nil)
if err != nil {
	log.Fatalf("error initializing app: %v\n", err)
}

С#

FirebaseApp.Create(new AppOptions()
{
    Credential = GoogleCredential.GetApplicationDefault(),
});

Введите учетные данные вручную

Проекты Firebase поддерживают учетные записи служб Google, которые вы можете использовать для вызова API-интерфейсов сервера Firebase с вашего сервера приложений или доверенной среды. Если вы разрабатываете код локально или развертываете приложение локально, вы можете использовать учетные данные, полученные через эту учетную запись службы, для авторизации запросов к серверу.

Чтобы аутентифицировать учетную запись службы и разрешить ей доступ к службам Firebase, вам необходимо создать файл закрытого ключа в формате JSON.

Чтобы создать файл закрытого ключа для вашей учетной записи службы:

  1. В консоли Firebase откройте «Настройки» > «Учетные записи служб» .

  2. Нажмите «Создать новый закрытый ключ» , затем подтвердите действие, нажав «Создать ключ» .

  3. Надежно сохраните файл JSON, содержащий ключ.

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

Чтобы установить переменную среды:

Задайте для переменной среды GOOGLE_APPLICATION_CREDENTIALS путь к файлу JSON, содержащему ключ вашей учетной записи службы. Эта переменная применяется только к текущему сеансу оболочки, поэтому, если вы открываете новый сеанс, установите переменную еще раз.

Линукс или МакОС

export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/service-account-file.json"

Окна

С PowerShell:

$env:GOOGLE_APPLICATION_CREDENTIALS="C:\Users\username\Downloads\service-account-file.json"

После того, как вы выполнили вышеуказанные шаги, учетные данные приложения по умолчанию (ADC) смогут неявно определять ваши учетные данные, позволяя вам использовать учетные данные учетной записи службы при тестировании или работе в средах, отличных от Google.

Используйте учетные данные для создания токенов доступа

Если вы не используете Admin SDK , который автоматически обрабатывает авторизацию, вам потребуется создать токен доступа и добавить его для отправки запросов.

Используйте свои учетные данные Firebase вместе с библиотекой Google Auth для предпочитаемого вами языка, чтобы получить недолговечный токен доступа OAuth 2.0:

узел.js

 function getAccessToken() {
  return new Promise(function(resolve, reject) {
    const key = require('../placeholders/service-account.json');
    const jwtClient = new google.auth.JWT(
      key.client_email,
      null,
      key.private_key,
      SCOPES,
      null
    );
    jwtClient.authorize(function(err, tokens) {
      if (err) {
        reject(err);
        return;
      }
      resolve(tokens.access_token);
    });
  });
}

В этом примере клиентская библиотека Google API проверяет подлинность запроса с помощью веб-токена JSON или JWT. Дополнительные сведения см. в разделе Веб-токены JSON .

Питон

def _get_access_token():
  """Retrieve a valid access token that can be used to authorize requests.

  :return: Access token.
  """
  credentials = service_account.Credentials.from_service_account_file(
    'service-account.json', scopes=SCOPES)
  request = google.auth.transport.requests.Request()
  credentials.refresh(request)
  return credentials.token

Ява

private static String getAccessToken() throws IOException {
  GoogleCredentials googleCredentials = GoogleCredentials
          .fromStream(new FileInputStream("service-account.json"))
          .createScoped(Arrays.asList(SCOPES));
  googleCredentials.refresh();
  return googleCredentials.getAccessToken().getTokenValue();
}

По истечении срока действия токена доступа метод обновления токена вызывается автоматически для получения обновленного токена доступа.

Чтобы авторизовать доступ к FCM , запросите область https://www.googleapis.com/auth/firebase.messaging .

Чтобы добавить токен доступа в заголовок HTTP-запроса:

Добавьте токен в качестве значения заголовка Authorization в формате Authorization: Bearer <access_token> :

узел.js

headers: {
  'Authorization': 'Bearer ' + accessToken
}

Питон

headers = {
  'Authorization': 'Bearer ' + _get_access_token(),
  'Content-Type': 'application/json; UTF-8',
}

Ява

URL url = new URL(BASE_URL + FCM_SEND_ENDPOINT);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestProperty("Authorization", "Bearer " + getServiceAccountAccessToken());
httpURLConnection.setRequestProperty("Content-Type", "application/json; UTF-8");
return httpURLConnection;

Разрешить запросы на отправку устаревшего протокола

При использовании устаревшего протокола HTTP каждый запрос должен содержать ключ сервера со вкладки Cloud Messaging на панели настроек консоли Firebase . Для XMPP вы должны использовать тот же ключ сервера для установления соединения.

Перенос ключей устаревшего сервера

Начиная с марта 2020 года FCM прекратил создавать устаревшие серверные ключи. Существующие устаревшие ключи сервера будут продолжать работать, но мы рекомендуем вместо этого использовать более новую версию ключа с надписью «Ключ сервера» в консоли Firebase .

Если вы хотите удалить существующий устаревший ключ сервера, вы можете сделать это в консоли Google Cloud .

Авторизовать HTTP-запросы

Запрос сообщения состоит из двух частей: HTTP-заголовка и HTTP-тела. Заголовок HTTP должен содержать следующие заголовки:

  • Authorization : ключ=ВАШ_СЕРВЕР_КЛЮЧ
    Убедитесь, что это ключ сервера , значение которого доступно на вкладке Cloud Messaging панели настроек консоли Firebase . Android, платформа Apple и ключи браузера отклоняются FCM .
  • Content-Type : application/json для JSON; application/x-www-form-urlencoded;charset=UTF-8 для обычного текста.
    Если Content-Type опущен, предполагается, что формат представляет собой обычный текст.

Например:

Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA

{
  "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
  "data" : {
    ...
  },
}

Подробную информацию о создании запросов на отправку см. в разделе Создание запросов на отправку. Справочник по устаревшему протоколу HTTP содержит список всех параметров, которые может содержать ваше сообщение.

Проверка действительности ключа сервера

Если при отправке сообщений вы получаете ошибки аутентификации, проверьте достоверность ключа вашего Сервера. Например, в Linux выполните следующую команду:

api_key=YOUR_SERVER_KEY

curl --header "Authorization: key=$api_key" \
     --header Content-Type:"application/json" \
     https://fcm.googleapis.com/fcm/send \
     -d "{\"registration_ids\":[\"ABC\"]}"

Если вы получили код состояния HTTP 401, ваш ключ сервера недействителен.

Авторизовать соединение XMPP

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

Вы можете использовать большинство библиотек XMPP для управления долговременным соединением с FCM . Конечная точка XMPP работает по адресу fcm-xmpp.googleapis.com:5235 . При тестировании функциональности с непроизводственными пользователями вместо этого следует подключиться к предварительному серверу по адресу fcm-xmpp.googleapis.com:5236 (обратите внимание на другой порт).

Регулярное тестирование на предварительной версии (небольшая среда, в которой запускаются последние сборки FCM ) полезно для изоляции реальных пользователей от тестового кода. Тестовые устройства и тестовый код, подключающиеся к fcm-xmpp.googleapis.com:5236 должны использовать другой идентификатор отправителя FCM , чтобы избежать каких-либо рисков отправки тестовых сообщений рабочим пользователям или отправки восходящих сообщений из рабочего трафика через тестовые соединения.

К подключению предъявляются два важных требования:

  • Вы должны инициировать соединение Transport Layer Security (TLS). Обратите внимание, что FCM в настоящее время не поддерживает расширение STARTTLS .
  • FCM требуется механизм аутентификации SASL PLAIN с использованием <your_ FCM _Sender_Id>@fcm.googleapis.com ( идентификатор отправителя FCM ) и ключа сервера в качестве пароля. Эти значения доступны на вкладке «Облачные сообщения» панели «Настройки консоли Firebase .

Если в какой-то момент соединение прервется, вам следует немедленно переподключиться. Нет необходимости отступать после отключения, которое происходит после аутентификации. Для каждого идентификатора отправителя FCM допускает 2500 параллельных подключений.

Следующие фрагменты показывают, как выполнить аутентификацию и авторизацию для соединения XMPP с FCM .

XMPP-сервер

Сервер XMPP запрашивает соединение с FCM

<stream:stream to="fcm.googleapis.com"
        version="1.0" xmlns="jabber:client"
        xmlns:stream="http://etherx.jabber.org/streams">

FCM

FCM открывает соединение и запрашивает механизм аутентификации, включая метод PLAIN .

<stream:features>
  <mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
    <mechanism>X-OAUTH2</mechanism>
    <mechanism>X-GOOGLE-TOKEN</mechanism>
    <mechanism>PLAIN</mechanism>
  </mechanisms>
</stream:features>

XMPP-сервер

Сервер XMPP должен ответить, используя метод аутентификации PLAIN , предоставив ключ сервера на вкладке Cloud Messaging на панели настроек консоли Firebase .

<auth mechanism="PLAIN"
xmlns="urn:ietf:params:xml:ns:xmpp-sasl">MTI2MjAwMzQ3OTMzQHByb2plY3RzLmdjbS5hb
mFTeUIzcmNaTmtmbnFLZEZiOW1oekNCaVlwT1JEQTJKV1d0dw==</auth>

FCM

<success xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/>

XMPP-сервер

<stream:stream to="fcm.googleapis.com"
        version="1.0" xmlns="jabber:client"
        xmlns:stream="http://etherx.jabber.org/streams">

FCM

<stream:features>
  <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/>
  <session xmlns="urn:ietf:params:xml:ns:xmpp-session"/>
</stream:features>

XMPP-сервер

<iq type="set">
  <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"></bind>
</iq>

FCM

<iq type="result">
  <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
    <jid>SENDER_ID@fcm.googleapis.com/RESOURCE</jid>
  </bind>
</iq>

Примечание. FCM не использует связанный ресурс при маршрутизации сообщений.

Подробную информацию о создании запросов на отправку см. в разделе Создание запросов на отправку. Справочник по устаревшему протоколу XMPP содержит список всех параметров, которые может содержать ваше сообщение.