Migracja ze starszych interfejsów API FCM na HTTP w wersji 1

Aplikacje korzystające ze starszych wersji interfejsów API FCM do obsługi protokołów HTTP i XMPP powinny jak najszybciej przejść na interfejs API HTTP v1. Wysyłanie wiadomości (w tym wiadomości nadrzędnych) za pomocą tych interfejsów API zostało wycofane 20 czerwca 2023 r. i zostanie usunięte 21 czerwca 2024 r.

Dowiedz się więcej o funkcjach, na które ta zmiana ma wpływ.

Oprócz stałej obsługi i nowych funkcji interfejs API HTTP w wersji 1 ma te zalety w porównaniu ze starszymi interfejsami API:

  • Lepsze zabezpieczenia dzięki tokenom dostępu Interfejs API HTTP w wersji 1 korzysta z tokenów dostępu o ograniczonym czasie ważności zgodnie z modelem zabezpieczeń OAuth2. Gdy token dostępu stanie się publiczny, będzie można go złośliwie użyć tylko przez godzinę, zanim straci ważność. Tokeny odświeżania nie są przesyłane tak często jak klucze bezpieczeństwa używane w starszym interfejsie API, więc prawdopodobieństwo ich przechwycenia jest znacznie mniejsze.

  • Bardziej efektywne dostosowywanie wiadomości na różnych platformach W przypadku treści wiadomości interfejs API HTTP w wersji 1 ma wspólne klucze, które trafiają do wszystkich instancji docelowych, oraz klucze odpowiednie dla platformy, które pozwalają dostosować wiadomość na różnych platformach. Pozwala to tworzyć „zastąpienia”, które wysyłają nieco inne ładunki do różnych platform klientów w jednej wiadomości.

  • Większa elastyczność i przyszłość w przypadku nowych wersji platformy klienta Interfejs API HTTP w wersji 1 w pełni obsługuje opcje przesyłania wiadomości dostępne na platformach Apple, Androidzie i w przeglądarce. Każda platforma ma własny zdefiniowany blok w ładunku JSON, więc FCM może w razie potrzeby rozszerzyć ten interfejs API na nowe wersje i platformy.

Zaktualizuj punkt końcowy serwera

Adres URL punktu końcowego interfejsu API HTTP w wersji 1 różni się od starszego punktu końcowego w następujący sposób:

  • Ma różne wersje ze ścieżką /v1.
  • Ścieżka zawiera identyfikator projektu Firebase dla Twojej aplikacji w formacie /projects/myproject-ID/. Ten identyfikator jest dostępny na karcie Ogólne ustawienia projektu w konsoli Firebase.
  • Jasno określa ona metodę send jako :send.

Aby zaktualizować punkt końcowy serwera na potrzeby protokołu HTTP w wersji 1, dodaj te elementy do punktu końcowego w nagłówku żądań wysyłania.

Żądania HTTP przed

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

Żądania XMPP przed

Starsze komunikaty XMPP są wysyłane przez połączenie do tego punktu końcowego:

fcm-xmpp.googleapis.com:5235

Po

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

Zaktualizuj autoryzację wysyłania żądań

W miejsce ciągu klucza serwera używanego w starszych żądaniach żądania wysyłania HTTP v1 wymagają tokena dostępu OAuth 2.0. Jeśli do wysyłania wiadomości używasz pakietu Admin SDK, biblioteka obsługuje token za Ciebie. Jeśli korzystasz z protokołu surowego, uzyskaj token zgodnie z tą sekcją i dodaj go do nagłówka jako Authorization: Bearer <valid Oauth 2.0 token>.

Przed

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

Po

Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA

W zależności od szczegółów środowiska serwera użyj kombinacji tych strategii, aby autoryzować żądania serwera do usług Firebase:

  • Domyślne uwierzytelnianie aplikacji Google (ADC)
  • Plik JSON konta usługi
  • o krótkotrwałym tokenie dostępu OAuth 2.0 pobranym z konta usługi;

Jeśli Twoja aplikacja działa w Compute Engine, Google Kubernetes Engine, App Engine lub Cloud Functions (w tym w Cloud Functions dla Firebase), użyj domyślnych danych uwierzytelniających aplikacji (ADC). ADC wykorzystuje istniejące domyślne konto usługi do uzyskiwania danych uwierzytelniających do autoryzowania żądań, a ADC umożliwia elastyczne testowanie lokalne za pomocą zmiennej środowiskowej GOOGLE_APPLICATION_CREDENTIALS. Aby uzyskać najpełniejszą automatyzację procesu autoryzacji, użyj ADC w połączeniu z bibliotekami serwera Admin SDK.

Jeśli Twoja aplikacja działa w środowisku serwera innym niż Google, musisz pobrać plik JSON konta usługi z projektu Firebase. Jeśli masz dostęp do systemu plików zawierającego plik klucza prywatnego, możesz używać zmiennej środowiskowej GOOGLE_APPLICATION_CREDENTIALS do autoryzacji żądań za pomocą tych ręcznie uzyskanych danych logowania. Jeśli nie masz dostępu do takiego pliku, musisz w kodzie odwoływać się do pliku konta usługi. Należy to robić z dużą ostrożnością, ponieważ istnieje ryzyko ujawnienia danych logowania.

Podaj dane logowania za pomocą ADC

Domyślne uwierzytelnianie aplikacji Google (ADC) sprawdza Twoje dane logowania w następującej kolejności:

  1. ADC sprawdza, czy jest ustawiona zmienna środowiskowa GOOGLE_APPLICATION_CREDENTIALS. Jeśli zmienna jest ustawiona, AC używa pliku konta usługi, do którego wskazuje zmienna.

  2. Jeśli zmienna środowiskowa nie jest ustawiona, ADC używa domyślnego konta usługi udostępnianego przez Compute Engine, Google Kubernetes Engine, App Engine i Cloud Functions dla aplikacji działających w tych usługach.

  3. Jeśli ADC nie będzie mogło użyć żadnego z podanych wyżej danych logowania, system zgłosi błąd.

Tę strategię ilustruje poniższy kod pakietu Admin SDK. W przykładzie nie podano wyraźnie danych logowania do aplikacji. ADC może jednak niejawnie znaleźć dane uwierzytelniające, jeśli jest ustawiona zmienna środowiskowa lub gdy aplikacja działa w Compute Engine, Google Kubernetes Engine, App Engine lub Cloud Functions.

Node.js

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

Java

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

FirebaseApp.initializeApp(options);

Python

default_app = firebase_admin.initialize_app()

Go

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

C#

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

Podaj dane logowania ręcznie

Projekty Firebase obsługują konta usługi Google, których możesz używać do wywoływania interfejsów API serwera Firebase z serwera aplikacji lub zaufanego środowiska. Jeśli tworzysz kod lokalnie lub wdrażasz aplikację lokalną, do autoryzowania żądań serwera możesz używać danych logowania uzyskanych za pomocą tego konta usługi.

Aby uwierzytelnić konto usługi i autoryzować je do uzyskiwania dostępu do usług Firebase, musisz wygenerować plik klucza prywatnego w formacie JSON.

Aby wygenerować plik klucza prywatnego dla konta usługi:

  1. W konsoli Firebase otwórz Ustawienia > Konta usługi.

  2. Kliknij Wygeneruj nowy klucz prywatny i potwierdź, klikając Wygeneruj klucz.

  3. Bezpiecznie przechowuj plik JSON zawierający klucz.

W przypadku autoryzacji za pomocą konta usługi masz 2 możliwości udostępnienia danych logowania do aplikacji. Możesz ustawić zmienną środowiskową GOOGLE_APPLICATION_CREDENTIALS lub przekazać w kodzie ścieżkę do klucza konta usługi. Pierwsza opcja jest bezpieczniejsza i zdecydowanie zalecamy jej stosowanie.

Aby ustawić zmienną środowiskową:

Ustaw zmienną środowiskową GOOGLE_APPLICATION_CREDENTIALS na ścieżkę pliku JSON zawierającego klucz konta usługi. Ta zmienna ma zastosowanie tylko do bieżącej sesji powłoki, więc jeśli otworzysz nową sesję, ustaw ją ponownie.

Linux lub macOS,

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

Windows

Za pomocą PowerShell:

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

Gdy wykonasz podane wyżej czynności, domyślne dane logowania aplikacji (ADC) będą mogły niejawnie określić Twoje dane logowania, dzięki czemu możesz używać danych logowania konta usługi podczas testowania lub uruchamiania ich w środowiskach innych niż Google.

Tworzenie tokenów dostępu przy użyciu danych logowania

Użyj swoich danych logowania Firebase razem z biblioteką uwierzytelniania Google dla preferowanego języka, aby pobrać token dostępu OAuth 2.0 o ograniczonym czasie ważności:

node.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);
    });
  });
}

W tym przykładzie biblioteka klienta interfejsu API Google uwierzytelnia żądanie za pomocą tokena sieciowego JSON (JWT). Więcej informacji znajdziesz w artykule o tokenach sieciowych JSON.

Python

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

Java

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();
}

Po wygaśnięciu tokena dostępu metoda odświeżania tokena jest wywoływana automatycznie w celu pobrania zaktualizowanego tokena dostępu.

Aby autoryzować dostęp do FCM, poproś o zakres https://www.googleapis.com/auth/firebase.messaging.

Aby dodać token dostępu do nagłówka żądania HTTP:

Dodaj token jako wartość nagłówka Authorization w formacie Authorization: Bearer <access_token>:

node.js

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

Python

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

Java

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;

Aktualizowanie ładunku żądań wysyłania

FCM HTTP v1 wprowadza znaczącą zmianę w strukturze ładunku wiadomości JSON. Przede wszystkim zmiany te zapewniają prawidłową obsługę wiadomości odbieranych na różnych platformach klienckich. Dodatkowo zmiany te zapewniają większą elastyczność dostosowywania lub „zastępowania” pól wiadomości w przypadku poszczególnych platform.

Oprócz zapoznania się z przykładami w tej sekcji przeczytaj sekcję Dostosowywanie wiadomości na różnych platformach oraz materiały referencyjne interfejsu API, aby poznać protokół HTTP w wersji 1.

Przykład: prosta wiadomość z powiadomieniem

Oto porównanie bardzo prostego ładunku powiadomienia, zawierającego tylko pola title, body i data, pokazujące zasadnicze różnice między ładunkami starszego typu i HTTP w wersji 1.

Przed

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

Po

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

Przykład: kierowanie na wiele platform

Aby umożliwić kierowanie na wiele platform, starsza wersja interfejsu API używała zastąpień w backendzie. Z kolei HTTP w wersji 1 udostępnia bloki kluczy właściwe dla danej platformy, które powodują różnice między platformami są jasne i widoczne dla dewelopera. Dzięki temu możesz kierować reklamy na wiele platform zawsze po 1 żądaniu, jak pokazano w tym przykładzie.

Przed

// 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"
  }
}

Po

{
  "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"
        }
      }
    }
  }
}

Przykład: dostosowanie za pomocą zastąpień platformy

Interfejs API HTTP w wersji 1 nie tylko upraszcza kierowanie wiadomości na wiele platform, ale też zapewnia elastyczność w dostosowywaniu wiadomości do poszczególnych platform.

Przed

// 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"
  }
}

Po

{
  "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"
        }
      }
    }
  }
}

Przykład: kierowanie na określone urządzenia

Aby kierować reklamy na określone urządzenia za pomocą interfejsu API HTTP w wersji 1, podaj w kluczu token bieżący token rejestracji urządzenia, a nie klucz to.

Przed

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

Po

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

Więcej przykładów i informacji o interfejsie FCM HTTP v1 API znajdziesz w tych artykułach: