了解 2023 年 Google I/O 大会上介绍的 Firebase 亮点。了解详情

Migra da HTTP legacy a HTTP v1

Le app che utilizzano l'API HTTP legacy di FCM dovrebbero prendere in considerazione la migrazione all'API HTTP v1 utilizzando le istruzioni in questa guida. L'API HTTP v1 presenta questi vantaggi rispetto all'API legacy:

  • Migliore sicurezza tramite token di accesso L'API HTTP v1 utilizza token di accesso di breve durata secondo il modello di sicurezza OAuth2. Nel caso in cui un token di accesso diventi pubblico, può essere utilizzato in modo dannoso solo per circa un'ora prima che scada. I token di aggiornamento non vengono trasmessi con la stessa frequenza delle chiavi di sicurezza utilizzate nell'API legacy, quindi è molto meno probabile che vengano acquisiti.

  • Personalizzazione più efficiente dei messaggi tra piattaforme Per il corpo del messaggio, l'API HTTP v1 dispone di chiavi comuni che vanno a tutte le istanze di destinazione, oltre a chiavi specifiche della piattaforma che consentono di personalizzare il messaggio tra piattaforme. Ciò consente di creare "override" che inviano payload leggermente diversi a diverse piattaforme client in un singolo messaggio.

  • Più estendibile e a prova di futuro per le nuove versioni della piattaforma client L'API HTTP v1 supporta completamente le opzioni di messaggistica disponibili su piattaforme Apple, Android e Web. Poiché ogni piattaforma ha il proprio blocco definito nel payload JSON, FCM può estendere l'API a nuove versioni e nuove piattaforme secondo necessità.

Aggiorna l'endpoint del server

L'URL dell'endpoint per l'API HTTP v1 differisce dall'endpont legacy nei seguenti modi:

  • È versionato, con /v1 nel percorso.
  • Il percorso contiene l'ID progetto del progetto Firebase per la tua app, nel formato /projects/myproject-ID/ . Questo ID è disponibile nella scheda Impostazioni generali del progetto della console Firebase.
  • Specifica esplicitamente il metodo send come :send .

Per aggiornare l'endpoint del server per HTTP v1, aggiungi questi elementi all'endpoint nell'intestazione delle tue richieste di invio.

Prima

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

Dopo

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

Aggiorna l'autorizzazione delle richieste di invio

Al posto della stringa della chiave del server utilizzata nelle richieste legacy, le richieste di invio HTTP v1 richiedono un token di accesso OAuth 2.0. Se utilizzi Admin SDK per inviare messaggi, la libreria gestisce il token per te. Se utilizzi il protocollo non elaborato, ottieni il token come descritto in questa sezione e aggiungilo all'intestazione come Authorization: Bearer <valid Oauth 2.0 token> .

Prima

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

Dopo

Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA

A seconda dei dettagli del tuo ambiente server, utilizza una combinazione di queste strategie per autorizzare le richieste del server ai servizi Firebase:

  • Credenziali predefinite dell'applicazione Google (ADC)
  • Un file JSON dell'account di servizio
  • Un token di accesso OAuth 2.0 di breve durata derivato da un account di servizio

Se la tua applicazione è in esecuzione su Compute Engine, Google Kubernetes Engine, App Engine o Cloud Functions (incluse le funzioni Cloud per Firebase), utilizza le credenziali predefinite dell'applicazione (ADC). ADC utilizza l'account di servizio predefinito esistente per ottenere le credenziali per autorizzare le richieste e ADC abilita test locali flessibili tramite la variabile di ambiente GOOGLE_APPLICATION_CREDENTIALS . Per la massima automazione del flusso di autorizzazione, utilizza ADC insieme alle librerie del server Admin SDK.

Se la tua applicazione è in esecuzione su un ambiente server diverso da Google , dovrai scaricare un file JSON dell'account di servizio dal tuo progetto Firebase. Finché hai accesso a un file system contenente il file della chiave privata, puoi utilizzare la variabile di ambiente GOOGLE_APPLICATION_CREDENTIALS per autorizzare le richieste con queste credenziali ottenute manualmente. Se non disponi di tale accesso al file, devi fare riferimento al file dell'account di servizio nel tuo codice, operazione che dovrebbe essere eseguita con estrema cautela a causa del rischio di esporre le tue credenziali.

Fornire le credenziali utilizzando ADC

Google Application Default Credentials (ADC) controlla le tue credenziali nel seguente ordine:

  1. ADC verifica se la variabile di ambiente GOOGLE_APPLICATION_CREDENTIALS è impostata. Se la variabile è impostata, ADC utilizza il file dell'account di servizio a cui punta la variabile.

  2. Se la variabile di ambiente non è impostata, ADC utilizza l'account di servizio predefinito fornito da Compute Engine, Google Kubernetes Engine, App Engine e Cloud Functions per le applicazioni eseguite su tali servizi.

  3. Se ADC non può usare nessuna delle credenziali precedenti, il sistema genera un errore.

Il seguente esempio di codice Admin SDK illustra questa strategia. L'esempio non specifica in modo esplicito le credenziali dell'applicazione. Tuttavia, ADC è in grado di trovare implicitamente le credenziali finché la variabile di ambiente è impostata o finché l'applicazione è in esecuzione su Compute Engine, Google Kubernetes Engine, App Engine o Cloud Functions.

Node.js

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

Giava

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

FirebaseApp.initializeApp(options);

Pitone

default_app = firebase_admin.initialize_app()

Andare

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

Fornire le credenziali manualmente

I progetti Firebase supportano gli account di servizio Google , che puoi utilizzare per chiamare le API del server Firebase dal tuo server dell'app o dall'ambiente attendibile. Se stai sviluppando codice in locale o distribuendo la tua applicazione in locale, puoi usare le credenziali ottenute tramite questo account di servizio per autorizzare le richieste del server.

Per autenticare un account di servizio e autorizzarlo ad accedere ai servizi Firebase, devi generare un file di chiave privata in formato JSON.

Per generare un file di chiave privata per il tuo account di servizio:

  1. Nella console Firebase, apri Impostazioni > Account di servizio .

  2. Fare clic su Genera nuova chiave privata , quindi confermare facendo clic su Genera chiave .

  3. Archivia in modo sicuro il file JSON contenente la chiave.

Quando autorizzi tramite un account di servizio, hai due possibilità per fornire le credenziali alla tua applicazione. Puoi impostare la variabile di ambiente GOOGLE_APPLICATION_CREDENTIALS oppure passare esplicitamente il percorso alla chiave dell'account di servizio nel codice. La prima opzione è più sicura ed è fortemente consigliata.

Per impostare la variabile di ambiente:

Imposta la variabile di ambiente GOOGLE_APPLICATION_CREDENTIALS sul percorso del file JSON che contiene la chiave dell'account di servizio. Questa variabile si applica solo alla tua sessione di shell corrente, quindi se apri una nuova sessione, imposta nuovamente la variabile.

Linux o macOS

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

finestre

Con PowerShell:

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

Dopo aver completato i passaggi precedenti, ADC (Application Default Credentials) è in grado di determinare implicitamente le tue credenziali, consentendoti di utilizzare le credenziali dell'account di servizio durante il test o l'esecuzione in ambienti non Google.

Usa le credenziali per coniare i token di accesso

Usa le tue credenziali Firebase insieme a Google Auth Library per la tua lingua preferita per recuperare un token di accesso OAuth 2.0 di breve durata:

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

In questo esempio, la libreria client dell'API di Google autentica la richiesta con un token Web JSON o JWT. Per ulteriori informazioni, consulta Token Web JSON .

Pitone

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

Giava

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

Dopo la scadenza del token di accesso, il metodo di aggiornamento del token viene chiamato automaticamente per recuperare un token di accesso aggiornato.

Per autorizzare l'accesso a FCM, richiedere l'ambito https://www.googleapis.com/auth/firebase.messaging .

Per aggiungere il token di accesso a un'intestazione di richiesta HTTP:

Aggiungere il token come valore dell'intestazione Authorization nel formato Authorization: Bearer <access_token> :

nodo.js

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

Pitone

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

Giava

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

Aggiorna il payload delle richieste di invio

FCM HTTP v1 introduce un cambiamento significativo nella strutturazione del payload del messaggio JSON. In primo luogo, queste modifiche assicurano che i messaggi vengano gestiti correttamente quando vengono ricevuti su diverse piattaforme client; inoltre, le modifiche offrono ulteriore flessibilità per personalizzare o "sovrascrivere" i campi dei messaggi per piattaforma.

Oltre a esaminare gli esempi in questa sezione, vedere Personalizzazione di un messaggio tra piattaforme e rivedere il riferimento API per acquisire familiarità con HTTP v1.

Esempio: semplice messaggio di notifica

Ecco un confronto di un payload di notifica molto semplice, contenente solo campi title , body e data , che dimostra le differenze fondamentali tra payload legacy e HTTP v1.

Prima

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

Dopo

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

Esempio: targeting per più piattaforme

Per abilitare il targeting per più piattaforme, l'API legacy ha eseguito l'override nel back-end. Al contrario, HTTP v1 fornisce blocchi di chiavi specifici della piattaforma che rendono esplicite e visibili allo sviluppatore eventuali differenze tra le piattaforme. Ciò consente di scegliere come target più piattaforme sempre con un'unica richiesta, come illustrato nell'esempio seguente.

Prima

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

Dopo

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

Esempio: personalizzazione con sostituzioni della piattaforma

Oltre a semplificare il targeting multipiattaforma dei messaggi, l'API HTTP v1 offre flessibilità per personalizzare i messaggi in base alla piattaforma.

Prima

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

Dopo

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

Esempio: targeting per dispositivi specifici

Per scegliere come target dispositivi specifici con l'API HTTP v1, fornisci il token di registrazione corrente del dispositivo nella chiave token anziché nella chiave to .

Prima

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

Dopo

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

Per ulteriori esempi e informazioni sull'API HTTP v1 di FCM, consulta il Blog di Firebase .