Autorizza le richieste di invio

Le richieste inviate a FCM dal server dell'app o dall'ambiente attendibile devono essere autorizzate. Tieni presente queste differenze importanti tra l'API HTTP precedente ritirata e l'autorizzazione dell'API HTTP v1:

  • L'API FCM HTTP v1 autorizza le richieste con un token di accesso OAuth 2.0 di breve durata. Per generare questo token, puoi utilizzare le credenziali predefinite dell'applicazione Google (negli ambienti server Google) e/o ottenere manualmente le credenziali richieste da un file di chiave privata JSON generato per un account di servizio. Se utilizzi Firebase Admin SDK per inviare messaggi, la libreria gestisce il token per te.
  • I protocolli precedenti ritirati possono utilizzare solo chiavi API a lungo termine ottenute dalla console Firebase.

Autorizza le richieste di invio HTTP v1

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

  • Credenziali predefinite dell'applicazione (ADC) di Google
  • 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 (incluso Cloud Functions for Firebase), utilizza le credenziali predefinite dell'applicazione (ADC). ADC utilizza il tuo account di servizio predefinito esistente per ottenere le credenziali per autorizzare le richieste e consente test locali flessibili tramite la variabile di ambienteGOOGLE_APPLICATION_CREDENTIALS. Per l'automazione completa del flusso di autorizzazione, utilizza ADC insieme alle librerie server di SDK Admin.

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

Fornisci le credenziali utilizzando ADC

Le Credenziali predefinite dell'applicazione (ADC) di Google cercano le tue credenziali nel seguente ordine:

  1. ADC controlla se la variabile di ambiente GOOGLE_APPLICATION_CREDENTIALS è impostata. Se la variabile è impostata, l'ADC utilizza il file dell'account di servizio a cui la variabile fa riferimento.

  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 in esecuzione su questi servizi.

  3. Se ADC non può utilizzare nessuna delle credenziali indicate sopra, il sistema genera un errore.

Il seguente esempio di codice dell'SDK Admin illustra questa strategia. L'esempio non specifica esplicitamente le credenziali dell'applicazione. Tuttavia, l'ADC è in grado di trovare implicitamente le credenziali purché la variabile di ambiente sia impostata o purché l'applicazione sia in esecuzione su Compute Engine, Google Kubernetes Engine, App Engine o 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()

Vai

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 di server Firebase dal server dell'app o dall'ambiente attendibile. Se stai sviluppando codice localmente o esegui il deployment dell'applicazione on-premise, puoi utilizzare le credenziali ottenute tramite questo account di servizio per autorizzare le richieste al server.

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

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

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

  2. Fai clic su Genera nuova chiave privata, poi conferma facendo clic su Genera chiave.

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

Quando esegui l'autorizzazione tramite un account di servizio, hai due opzioni per fornire le credenziali alla tua applicazione. Puoi impostare la variabile di ambiente GOOGLE_APPLICATION_CREDENTIALS o passare esplicitamente il percorso della chiave dell'account di servizio nel codice. La prima opzione è più sicura ed è vivamente consigliata.

Per impostare la variabile di ambiente:

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

Linux o macOS

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

Windows

Con PowerShell:

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

Dopo aver completato i passaggi precedenti, le credenziali predefinite dell'applicazione (ADC) possono determinare implicitamente le tue credenziali, consentendoti di utilizzare le credenziali dell'account servizio durante i test o l'esecuzione in ambienti non Google.

Usa le credenziali per creare i token di accesso

A meno che tu non stia utilizzando l'SDK Admin, che gestisce automaticamente l'autorizzazione, dovrai creare il token di accesso e aggiungerlo per inviare le richieste.

Utilizza le tue credenziali Firebase insieme alla libreria di autenticazione Google per la tua lingua preferita per recuperare un token di accesso OAuth 2.0 di breve durata:

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

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.

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

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, richiedi l'ambito https://www.googleapis.com/auth/firebase.messaging.

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

Aggiungi il token come valore dell'intestazione Authorization nel formato 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;

Autorizzare le richieste di invio del protocollo precedente

Con il protocollo legacy HTTP, ogni richiesta deve contenere la chiave server della scheda Cloud Messaging del riquadro Impostazioni della console Firebase. Per XMPP, devi utilizzare la stessa chiave del server per stabilire una connessione.

Esegui la migrazione delle chiavi server precedenti

A partire da marzo 2020, FCM ha smesso di creare chiavi server precedenti. Le chiavi di server precedenti continueranno a funzionare, ma ti consigliamo di utilizzare la versione più recente della chiave etichettata come Chiave di server nella console Firebase.

Se vuoi eliminare una chiave server precedente esistente, puoi farlo nella console Google Cloud.

Autorizzare le richieste HTTP

Una richiesta di messaggio è costituita da due parti: l'intestazione HTTP e il corpo HTTP. L'intestazione HTTP deve contenere le seguenti intestazioni:

  • Authorization: key=YOUR_SERVER_KEY
    Assicurati che si tratti della chiave del server, il cui valore è disponibile nella scheda Cloud Messaging del riquadro Impostazioni della console Firebase. Le chiavi di Android, della piattaforma Apple e del browser sono state rifiutate da FCM.
  • Content-Type: application/json per JSON; application/x-www-form-urlencoded;charset=UTF-8 per testo normale.
    Se il campo Content-Type viene omesso, si presume che il formato sia di testo normale.

Ad esempio:

Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA

{
  "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
  "data" : {
    ...
  },
}

Per informazioni dettagliate sulla creazione delle richieste di invio, consulta la sezione Creare richieste di invio. La documentazione di riferimento del protocollo HTTP precedente fornisce un elenco di tutti i parametri che il messaggio può contenere.

Controllare la validità di una chiave server

Se ricevi errori di autenticazione durante l'invio di messaggi, controlla la validità della chiave del server. Ad esempio, su Linux, esegui questo comando:

api_key=YOUR_SERVER_KEY

curl --header "Authorization: key=$api_key" \
     --header Content-Type:"application/json" \
     https://fcm.googleapis.com/fcm/send \
     -d "{\"registration_ids\":[\"ABC\"]}"

Se ricevi un codice di stato HTTP 401, la chiave del server non è valida.

Autorizzare una connessione XMPP

Con XMPP, puoi mantenere una connessione permanente, asincrona e bidirezionale ai server FCM. La connessione può essere utilizzata per inviare e ricevere messaggi tra il tuo server e i dispositivi connessi a FCM dei tuoi utenti.

Puoi utilizzare la maggior parte delle librerie XMPP per gestire una connessione di lunga durata a FCM. L'endpoint XMPP viene eseguito alle ore fcm-xmpp.googleapis.com:5235. Quando testi la funzionalità con utenti non di produzione, devi invece connetterti al server di pre-produzione all'indirizzo fcm-xmpp.googleapis.com:5236 (nota la diversa porta).

I test regolari in preproduzione (un ambiente più piccolo in cui vengono eseguite le build FCM più recenti) sono utili per isolare gli utenti reali dal codice di test. I dispositivi di test e il codice di test che si connettono a fcm-xmpp.googleapis.com:5236 devono utilizzare un ID mittente FCM diverso per evitare qualsiasi rischio di inviare messaggi di test a utenti di produzione o inviare messaggi upstream dal traffico di produzione tramite connessioni di test.

La connessione ha due requisiti importanti:

  • Devi avviare una connessione Transport Layer Security (TLS). Tieni presente che FCM al momento non supporta l'estensione STARTTLS.
  • FCM richiede un meccanismo di autenticazione SASL PLAIN che utilizzi <your_FCM_Sender_Id>@fcm.googleapis.com (FCM ID mittente) e la chiave del server come password. Questi valori sono disponibili nella scheda Cloud Messaging del riquadro Impostazioni della console Firebase.

Se in un determinato momento la connessione non va a buon fine, devi riconnetterti immediatamente. Non è necessario annullare la disconnessione dopo una disconnessione che avviene dopo l'autenticazione. Per ogni ID mittente, FCM consente 2500 connessioni in parallelo.

Gli snippet seguenti illustrano come eseguire l'autenticazione e l'autorizzazione per una connessione XMPP a FCM.

Server XMPP

Il server XMPP richiede una connessione a FCM

<stream:stream to="fcm.googleapis.com"
        version="1.0" xmlns="jabber:client"
        xmlns:stream="http://etherx.jabber.org/streams">

FCM

FCM apre la connessione e richiede un meccanismo di autenticazione, incluso il metodo PLAIN.

<stream:features>
  <mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
    <mechanism>X-OAUTH2</mechanism>
    <mechanism>X-GOOGLE-TOKEN</mechanism>
    <mechanism>PLAIN</mechanism>
  </mechanisms>
</stream:features>

Server XMPP

Il server XMPP deve rispondere utilizzando il metodo di autenticazione PLAIN, fornendo la chiave server dalla scheda Cloud Messaging del riquadro Impostazioni della console Firebase.

<auth mechanism="PLAIN"
xmlns="urn:ietf:params:xml:ns:xmpp-sasl">MTI2MjAwMzQ3OTMzQHByb2plY3RzLmdjbS5hb
mFTeUIzcmNaTmtmbnFLZEZiOW1oekNCaVlwT1JEQTJKV1d0dw==</auth>

FCM

<success xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/>

Server XMPP

<stream:stream to="fcm.googleapis.com"
        version="1.0" xmlns="jabber:client"
        xmlns:stream="http://etherx.jabber.org/streams">

FCM

<stream:features>
  <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/>
  <session xmlns="urn:ietf:params:xml:ns:xmpp-session"/>
</stream:features>

Server XMPP

<iq type="set">
  <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"></bind>
</iq>

FCM

<iq type="result">
  <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
    <jid>SENDER_ID@fcm.googleapis.com/RESOURCE</jid>
  </bind>
</iq>

Nota: FCM non utilizza la risorsa associata durante l'instradamento dei messaggi.

Per informazioni dettagliate sulla creazione delle richieste di invio, consulta la sezione Creare richieste di invio. Il riferimento sul protocollo XMPP legacy offre un elenco di tutti i parametri che il messaggio può contenere.