Passer des anciennes API FCM à HTTP v1

Les applications qui utilisent les anciennes API FCM obsolètes pour HTTP et XMPP doivent migrer vers l'API HTTP v1 dès que possible. L'envoi de messages (y compris les messages en amont) avec ces API a été abandonné le 20 juin 2023, et l'arrêt commencera le 22 juillet 2024.

En savoir plus sur les fonctionnalités concernées

En plus d'une assistance continue et de nouvelles fonctionnalités, l'API HTTP v1 présente les avantages suivants par rapport aux anciennes API:

  • Meilleure sécurité grâce aux jetons d'accès L'API HTTP v1 utilise des jetons d'accès à durée de vie limitée conformément au modèle de sécurité OAuth2. Si un jeton d'accès devient public, il ne peut être utilisé de manière malveillante que pendant une heure environ avant d'expirer. Les jetons d'actualisation ne sont pas transmis aussi souvent que les clés de sécurité utilisées dans l'ancienne API. Ils sont donc beaucoup moins susceptibles d'être capturés.

  • Personnalisation plus efficace des messages sur les différentes plates-formes Pour le corps du message, l'API HTTP v1 comporte des clés communes qui s'appliquent à toutes les instances ciblées, ainsi que des clés spécifiques à la plate-forme qui vous permettent de personnaliser le message sur les différentes plates-formes. Vous pouvez ainsi créer des "forcements" qui envoient des charges utiles légèrement différentes à différentes plates-formes clientes dans un seul message.

  • Plus extensible et évolutif pour les nouvelles versions de plates-formes clientes L'API HTTP v1 est entièrement compatible avec les options de messagerie disponibles sur les plates-formes Apple, Android et Web. Étant donné que chaque plate-forme dispose de son propre bloc défini dans la charge utile JSON, FCM peut étendre l'API à de nouvelles versions et à de nouvelles plates-formes si nécessaire.

Mettre à jour le point de terminaison du serveur

L'URL du point de terminaison de l'API HTTP v1 diffère de l'ancien point de terminaison comme suit:

  • Il est versionné, avec /v1 dans le chemin d'accès.
  • Le chemin d'accès contient l'ID du projet Firebase de votre application, au format /projects/myproject-ID/. Cet ID est disponible dans l'onglet Paramètres généraux du projet de la console Firebase.
  • Il spécifie explicitement la méthode send en tant que :send.

Pour mettre à jour le point de terminaison du serveur pour HTTP v1, ajoutez ces éléments au point de terminaison dans l'en-tête de vos requêtes d'envoi.

Requêtes HTTP avant

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

Demandes XMPP avant

Les anciens messages XMPP sont envoyés via une connexion au point de terminaison suivant:

fcm-xmpp.googleapis.com:5235

Après

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

Mettre à jour l'autorisation des demandes d'envoi

Au lieu de la chaîne de clé de serveur utilisée dans les anciennes requêtes, les requêtes d'envoi HTTP v1 nécessitent un jeton d'accès OAuth 2.0. Si vous utilisez le SDK Admin pour envoyer des messages, la bibliothèque gère le jeton à votre place. Si vous utilisez le protocole brut de l'API Azure Storage, obtenez le jeton comme décrit dans cette section et ajoutez-le à l'en-tête en tant que Authorization: Bearer <valid Oauth 2.0 token>.

Avant

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

Après

Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA

En fonction des détails de votre environnement serveur, utilisez une combinaison de ces stratégies pour autoriser les requêtes de serveur aux services Firebase:

  • Identifiants par défaut de l'application (ADC) Google
  • Fichier JSON du compte de service
  • Un jeton d'accès OAuth 2.0 de courte durée dérivé d'un compte de service

Si votre application s'exécute sur Compute Engine, Google Kubernetes Engine, App Engine ou Cloud Functions (y compris Cloud Functions for Firebase), utilisez les identifiants par défaut de l'application (ADC). L'ADC utilise votre compte de service par défaut existant pour obtenir des identifiants permettant d'autoriser les requêtes. Il permet également d'effectuer des tests locaux flexibles via la variable d'environnement GOOGLE_APPLICATION_CREDENTIALS. Pour une automatisation optimale du flux d'autorisation, utilisez l'ADC avec les bibliothèques de serveurs du SDK Admin.

Si votre application s'exécute dans un environnement serveur autre que Google, vous devez télécharger un fichier JSON de compte de service à partir de votre projet Firebase. Tant que vous avez accès à un système de fichiers contenant le fichier de clé privée, vous pouvez utiliser la variable d'environnement GOOGLE_APPLICATION_CREDENTIALS pour autoriser les requêtes avec ces identifiants obtenus manuellement. Si vous ne disposez pas de cet accès aux fichiers, vous devez référencer le fichier de compte de service dans votre code, ce qui doit être fait avec une extrême prudence en raison du risque d'exposer vos identifiants.

Fournir des identifiants à l'aide de l'ADC

Les identifiants par défaut de l'application (ADC) de Google recherchent vos identifiants dans l'ordre suivant:

  1. L'ADC vérifie si la variable d'environnement GOOGLE_APPLICATION_CREDENTIALS est définie. Si elle est définie, l'ADC utilise le fichier de compte de service vers lequel la variable renvoie.

  2. Si la variable d'environnement n'est pas définie, ADC utilise le compte de service par défaut fourni par Compute Engine, Google Kubernetes Engine, App Engine et Cloud Functions pour les applications exécutées sur ces services.

  3. Si l'ADC ne peut utiliser aucune des informations d'identification ci-dessus, le système génère une erreur.

L'exemple de code du SDK Admin suivant illustre cette stratégie. Il n'indique pas explicitement les identifiants de l'application. Toutefois, l'ADC est capable de trouver implicitement les identifiants tant que la variable d'environnement est définie, ou tant que l'application s'exécute sur Compute Engine, Google Kubernetes Engine, App Engine ou 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(),
});

Fournir des identifiants manuellement

Les projets Firebase sont compatibles avec les comptes de service Google, que vous pouvez utiliser pour appeler les API de serveur Firebase à partir de votre serveur d'application ou de votre environnement approuvé. Si vous développez du code localement ou déployez votre application sur site, vous pouvez utiliser les identifiants obtenus via ce compte de service pour autoriser les requêtes du serveur.

Pour authentifier un compte de service et l'autoriser à accéder aux services Firebase, vous devez générer un fichier de clé privée au format JSON.

Pour générer un fichier de clé privée pour votre compte de service:

  1. Dans la console Firebase, ouvrez Settings > Service Accounts (Paramètres > Comptes de service).

  2. Cliquez sur Générer une nouvelle clé privée, puis confirmez en cliquant sur Générer une clé.

  3. Stockez de manière sécurisée le fichier JSON contenant la clé.

Lorsque vous autorisez l'accès via un compte de service, vous avez deux choix pour fournir les identifiants à votre application. Vous pouvez définir la variable d'environnement GOOGLE_APPLICATION_CREDENTIALS ou transmettre explicitement le chemin d'accès à la clé du compte de service dans le code. La première option est plus sécurisée et est vivement recommandée.

Pour définir la variable d'environnement:

Définissez la variable d'environnement GOOGLE_APPLICATION_CREDENTIALS pour qu'elle pointe vers le chemin du fichier JSON contenant la clé de votre compte de service. Cette variable ne s'applique qu'à la session de shell actuelle. Par conséquent, si vous ouvrez une nouvelle session, vous devez la définir à nouveau.

Linux ou macOS

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

Windows

Avec PowerShell :

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

Une fois que vous avez terminé les étapes ci-dessus, les identifiants par défaut de l'application (ADC) peuvent déterminer implicitement vos identifiants, ce qui vous permet d'utiliser les identifiants du compte de service lors des tests ou de l'exécution dans des environnements autres que Google.

Utiliser des identifiants pour créer des jetons d'accès

Utilisez vos identifiants Firebase avec la bibliothèque Google Auth dans la langue de votre choix pour récupérer un jeton d'accès OAuth 2.0 de courte durée:

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

Dans cet exemple, la bibliothèque cliente de l'API Google authentifie la requête avec un jeton Web JSON (JWT). Pour en savoir plus, consultez la section Jetons Web 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();
}

Une fois votre jeton d'accès expiré, la méthode d'actualisation du jeton est appelée automatiquement pour récupérer un jeton d'accès mis à jour.

Pour autoriser l'accès à FCM, demandez le champ d'application https://www.googleapis.com/auth/firebase.messaging.

Pour ajouter le jeton d'accès à un en-tête de requête HTTP:

Ajoutez le jeton en tant que valeur de l'en-tête Authorization au format 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;

Modifier la charge utile des requêtes d'envoi

FCM HTTP v1 introduit un changement important dans la structuration de la charge utile du message JSON. Ces modifications permettent principalement de s'assurer que les messages sont correctement gérés lorsqu'ils sont reçus sur différentes plates-formes clientes. De plus, elles vous offrent une flexibilité supplémentaire pour personnaliser ou "forcer" les champs de message par plate-forme.

En plus d'examiner les exemples de cette section, consultez Personnaliser un message sur plusieurs plates-formes et consultez la documentation de référence de l'API pour vous familiariser avec HTTP v1.

Exemple: message de notification simple

Voici une comparaison d'une charge utile de notification très simple (contenant uniquement les champs title, body et data) qui illustre les différences fondamentales entre les charges utiles héritées et HTTP v1.

Avant

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

Après

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

Exemple: données JSON imbriquées

Contrairement à l'ancienne API de messagerie, l'API HTTP v1 n'est pas compatible avec les valeurs JSON imbriquées dans le champ data. Une conversion de JSON en chaîne est requise.

Avant

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

Après

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

Exemple: Ciblage de plusieurs plates-formes

Pour activer le ciblage multiplate-forme, l'ancienne API effectuait des forçages dans le backend. En revanche, HTTP v1 fournit des blocs de clés spécifiques à la plate-forme qui rendent les différences entre les plates-formes explicites et visibles pour le développeur. Vous pouvez ainsi cibler plusieurs plates-formes avec une seule requête, comme illustré dans l'exemple suivant.

Avant

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

Après

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

Exemple: Personnalisation avec des forçages de plate-forme

En plus de simplifier le ciblage multiplate-forme des messages, l'API HTTP v1 offre la flexibilité nécessaire pour personnaliser les messages par plate-forme.

Avant

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

Après

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

Exemple: Cibler des appareils spécifiques

Pour cibler des appareils spécifiques avec l'API HTTP v1, fournissez le jeton d'enregistrement actuel de l'appareil dans la clé token au lieu de la clé to.

Avant

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

Après

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

Pour obtenir d'autres exemples et plus d'informations sur l'API HTTP v1 FCM, consultez les ressources suivantes: