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

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

Узнайте больше о конкретных функциях, на которые это влияет .

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

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

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

  • Более расширяемый и перспективный для новых версий клиентских платформ HTTP v1 API полностью поддерживает опции обмена сообщениями, доступные на платформах Apple, Android и Web. Поскольку каждая платформа имеет свой собственный определенный блок в полезной нагрузке 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 или Cloud Functions (включая Cloud Functions for Firebase ), используйте Application Default Credentials (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, содержащему ключ вашего сервисного аккаунта. Эта переменная применяется только к текущему сеансу оболочки, поэтому, если вы открываете новый сеанс, установите переменную снова.

Linux или macOS

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

Окна

С PowerShell:

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

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

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

Используйте свои учетные данные Firebase вместе с библиотекой Google Auth Library для предпочитаемого вами языка, чтобы получить кратковременный токен доступа 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);
    });
  });
}

В этом примере клиентская библиотека API Google аутентифицирует запрос с помощью веб-токена 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"
    }
  }
}

Пример: вложенные данные JSON

В отличие от устаревшего API обмена сообщениями, API HTTP v1 не поддерживает вложенные значения JSON в поле data . Требуется преобразование из JSON в строку.

До

{
  ...
  "data": {
    "keysandvalues": {"key1": "value1", "key2": 123}
  }
}

После

{
  "message": {
   ...
    "data": {
      "keysandvalues": "{\"key1\": \"value1\", \"key2\": 123}"
    }
  }
}

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

Чтобы включить многоплатформенный таргетинг, устаревший 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!",
      "title": "FCM Message"
    },
    "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
  }

После

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

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