Переход с устаревших API FCM на HTTP v1

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

Помимо постоянной поддержки и новых функций, API HTTP v1 имеет следующие преимущества перед устаревшими API:

  • Повышенная безопасность с помощью токенов доступа API HTTP v1 использует кратковременные токены доступа в соответствии с моделью безопасности OAuth2. В случае, если токен доступа становится общедоступным, его можно будет использовать злонамеренно только в течение часа или около того, прежде чем истечет срок его действия. Токены обновления передаются не так часто, как ключи безопасности, используемые в устаревшем API, поэтому вероятность их перехвата гораздо ниже.

  • Более эффективная настройка сообщений на разных платформах . Для тела сообщения API HTTP v1 имеет общие ключи, которые относятся ко всем целевым экземплярам, ​​а также ключи для конкретной платформы, которые позволяют настраивать сообщение на разных платформах. Это позволяет создавать «переопределения», которые отправляют несколько разные полезные данные на разные клиентские платформы в одном сообщении.

  • Более расширяемый и ориентированный на будущее для новых версий клиентской платформы API HTTP v1 полностью поддерживает параметры обмена сообщениями, доступные на платформах Apple, Android и в Интернете. Поскольку каждая платформа имеет свой собственный определенный блок в полезных данных JSON, FCM может при необходимости расширять API для новых версий и новых платформ.

Обновите конечную точку сервера

URL-адрес конечной точки для API HTTP v1 отличается от устаревшей конечной точки следующим образом:

  • Он имеет версию с /v1 в пути.
  • Путь содержит идентификатор проекта Firebase для вашего приложения в формате /projects/myproject-ID/ . Этот идентификатор доступен на вкладке «Общие настройки проекта» консоли Firebase.
  • Он явно указывает метод send как :send .

Чтобы обновить конечную точку сервера для HTTP v1, добавьте эти элементы в конечную точку в заголовке ваших запросов на отправку.

HTTP-запросы раньше

POST https://fcm.googleapis.com/fcm/send

XMPP запросы раньше

Устаревшие сообщения XMPP отправляются через соединение со следующей конечной точкой:

fcm-xmpp.googleapis.com:5235

После

POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send

Обновление авторизации запросов на отправку

Вместо строки ключа сервера, используемой в устаревших запросах, для запросов на отправку HTTP v1 требуется токен доступа OAuth 2.0. Если вы используете Admin SDK для отправки сообщений, библиотека обрабатывает токен за вас. Если вы используете необработанный протокол, получите токен, как описано в этом разделе, и добавьте его в заголовок как Authorization: Bearer <valid Oauth 2.0 token> .

До

Authorization: key=AIzaSyZ-1u...0GBYzPu7Udno5aA

После

Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA

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

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

Если ваше приложение работает на Compute Engine, Google Kubernetes Engine, App Engine или облачных функциях (включая облачные функции для 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.

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

Используйте свои учетные данные 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;

Обновить полезную нагрузку запросов на отправку

FCM HTTP v1 вносит существенные изменения в структурирование полезной нагрузки сообщения JSON. Прежде всего, эти изменения гарантируют правильную обработку сообщений при их получении на разных клиентских платформах; кроме того, изменения дают вам дополнительную гибкость в настройке или «переопределении» полей сообщений для каждой платформы.

Помимо изучения примеров в этом разделе, см. раздел Настройка сообщения на разных платформах и просмотрите справочник по API , чтобы познакомиться с HTTP v1.

Пример: простое уведомление

Вот сравнение очень простой полезной нагрузки уведомления, содержащей только title , body и поля data , демонстрирующее фундаментальные различия в устаревшей полезной нагрузке и HTTP v1.

До

{
  "to": "/topics/news",
  "notification": {
    "title": "Breaking News",
    "body": "New news story available."
  },
  "data": {
    "story_id": "story_12345"
  }
}

После

{
  "message": {
    "topic": "news",
    "notification": {
      "title": "Breaking News",
      "body": "New news story available."
    },
    "data": {
      "story_id": "story_12345"
    }
  }
}

Пример: таргетинг на несколько платформ

Чтобы включить таргетинг на несколько платформ, устаревший API переопределял серверную часть. Напротив, HTTP v1 предоставляет специфичные для платформы блоки ключей, которые делают любые различия между платформами явными и видимыми для разработчика. Это позволяет вам всегда обращаться к нескольким платформам с помощью одного запроса, как показано в следующем примере.

До

// Android
{
  "to": "/topics/news",
  "notification": {
    "title": "Breaking News",
    "body": "New news story available.",
    "click_action": "TOP_STORY_ACTIVITY"
  },
  "data": {
    "story_id": "story_12345"
  }
}
// Apple
{
  "to": "/topics/news",
  "notification": {
    "title": "Breaking News",
    "body": "New news story available.",
    "click_action": "HANDLE_BREAKING_NEWS"
  },
  "data": {
    "story_id": "story_12345"
  }
}

После

{
  "message": {
    "topic": "news",
    "notification": {
      "title": "Breaking News",
      "body": "New news story available."
    },
    "data": {
      "story_id": "story_12345"
    },
    "android": {
      "notification": {
        "click_action": "TOP_STORY_ACTIVITY"
      }
    },
    "apns": {
      "payload": {
        "aps": {
          "category" : "NEW_MESSAGE_CATEGORY"
        }
      }
    }
  }
}

Пример: настройка с переопределением платформы

Помимо упрощения кросс-платформенного таргетинга сообщений, API HTTP v1 обеспечивает гибкость настройки сообщений для каждой платформы.

До

// Android
{
  "to": "/topics/news",
  "notification": {
    "title": "Breaking News",
    "body": "Check out the Top Story.",
    "click_action": "TOP_STORY_ACTIVITY"
  },
  "data": {
    "story_id": "story_12345"
  }
}
// Apple
{
  "to": "/topics/news",
  "notification": {
    "title": "Breaking News",
    "body": "New news story available.",
    "click_action": "HANDLE_BREAKING_NEWS"
  },
  "data": {
    "story_id": "story_12345"
  }
}

После

{
  "message": {
    "topic": "news",
    "notification": {
      "title": "Breaking News",
      "body": "New news story available."
    },
    "data": {
      "story_id": "story_12345"
    },
    "android": {
      "notification": {
        "click_action": "TOP_STORY_ACTIVITY",
        "body": "Check out the Top Story"
      }
    },
    "apns": {
      "payload": {
        "aps": {
          "category" : "NEW_MESSAGE_CATEGORY"
        }
      }
    }
  }
}

Пример: таргетинг на определенные устройства

Чтобы настроить таргетинг на определенные устройства с помощью API HTTP v1, укажите текущий токен регистрации устройства в ключе token вместо ключа to .

До

  { "notification": {
      "body": "This is an FCM notification message!",
      "time": "FCM Message"
    },
    "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
  }

После

{
   "message":{
      "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
      "notification":{
        "body":"This is an FCM notification message!",
        "title":"FCM Message"
      }
   }
}

Дополнительные примеры и информацию об API FCM HTTP v1 см. в следующих разделах: