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

Il tuo ambiente server e FCM

Il lato server di Firebase Cloud Messaging è costituito da due componenti:

  • Il backend FCM fornito da Google.
  • Il tuo server dell'app o altro ambiente server attendibile in cui viene eseguita la logica del server, ad esempio Cloud Functions per Firebase o altri ambienti cloud gestiti da Google.

L'app server o l'ambiente del server attendibile invia richieste di messaggi al back-end FCM, che quindi instrada i messaggi alle app client in esecuzione sui dispositivi degli utenti.

Requisiti per l'ambiente del server attendibile

Il tuo ambiente del server delle applicazioni deve soddisfare i seguenti criteri:

  • In grado di inviare richieste di messaggi correttamente formattate al backend FCM.
  • In grado di gestire le richieste e inviarle nuovamente utilizzando il backoff esponenziale.
  • In grado di archiviare in modo sicuro le credenziali di autorizzazione del server e i token di registrazione del client.
  • Per il protocollo XMPP (se utilizzato), il server deve essere in grado di generare ID messaggio per identificare in modo univoco ogni messaggio che invia (il backend HTTP FCM genera ID messaggio e li restituisce nella risposta). Gli ID messaggio XMPP devono essere univoci per ID mittente.

Scelta di un'opzione server

Dovrai decidere un modo per interagire con i server FCM: utilizzando l' SDK Firebase Admin o i protocolli non elaborati. A causa del suo supporto attraverso i linguaggi di programmazione più diffusi e dei suoi metodi pratici per la gestione dell'autenticazione e dell'autorizzazione, l'SDK Firebase Admin è il metodo consigliato.

Le opzioni per l'interazione con i server FCM includono quanto segue:

  • Firebase Admin SDK, che supporta Node , Java , Python , C# e Go .
  • L' API FCM HTTP v1 , che è la più aggiornata delle opzioni di protocollo, con autorizzazione più sicura e funzionalità di messaggistica multipiattaforma flessibili (l'SDK Firebase Admin è basato su questo protocollo e offre tutti i suoi vantaggi intrinseci). Poiché in genere le nuove funzionalità vengono aggiunte solo all'API HTTP v1, ti consigliamo di utilizzare questa API per la maggior parte dei casi d'uso.
  • Il protocollo HTTP legacy . Si consiglia vivamente ai nuovi progetti di adottare l'API HTTP di FCM v1 invece del protocollo legacy.
  • Il protocollo del server XMPP legacy . Si consiglia vivamente ai nuovi progetti di adottare l'API HTTP di FCM v1 invece del protocollo legacy.

SDK Firebase Admin per FCM

L'API Admin FCM gestisce l'autenticazione con il back-end e facilita l'invio di messaggi e la gestione delle sottoscrizioni agli argomenti. Con Firebase Admin SDK, puoi:

  • Invia messaggi a singoli dispositivi
  • Invia messaggi ad argomenti e dichiarazioni di condizione che corrispondono a uno o più argomenti.
  • Iscrivere e annullare l'iscrizione dei dispositivi da e verso gli argomenti
  • Costruisci payload di messaggi su misura per diverse piattaforme di destinazione

L'SDK Admin Node.js fornisce metodi per l'invio di messaggi a gruppi di dispositivi.

Per configurare l'SDK Firebase Admin, consulta Aggiungere l'SDK Firebase Admin al tuo server . Se hai già un progetto Firebase, inizia con Aggiungi l'SDK . Inoltre, assicurati di abilitare l'API Cloud Messagin nella pagina delle impostazioni di Cloud Messaging per il tuo progetto. Quindi, una volta installato l'SDK Firebase Admin, puoi iniziare a scrivere la logica per creare le richieste di invio .

Protocolli del server FCM

Attualmente FCM fornisce questi protocolli server non elaborati:

Il tuo server app può utilizzare questi protocolli separatamente o in tandem. Poiché è la più aggiornata e la più flessibile per l'invio di messaggi a più piattaforme, l'API FCM HTTP v1 è consigliata ove possibile. Se i tuoi requisiti includono la messaggistica upstream dai dispositivi al server, dovrai implementare il protocollo XMPP.

La messaggistica XMPP differisce dalla messaggistica HTTP nei seguenti modi:

  • Messaggi a monte/a valle
    • HTTP: solo downstream, da cloud a dispositivo.
    • XMPP: upstream e downstream (da dispositivo a cloud, da cloud a dispositivo).
  • Messaggistica (sincrona o asincrona)
    • HTTP: sincrono. I server delle applicazioni inviano messaggi come richieste HTTP POST e attendono una risposta. Questo meccanismo è sincrono e impedisce al mittente di inviare un altro messaggio finché non viene ricevuta la risposta.
    • XMPP: asincrono. I server delle applicazioni inviano/ricevono messaggi da/a tutti i loro dispositivi alla massima velocità della linea tramite connessioni XMPP persistenti. Il server di connessione XMPP invia notifiche di riconoscimento o di errore (sotto forma di speciali messaggi XMPP con codifica JSON ACK e NACK) in modo asincrono.
  • JSON
    • HTTP: messaggi JSON inviati come HTTP POST.
    • XMPP: messaggi JSON incapsulati in messaggi XMPP.
  • Testo semplice
    • HTTP: messaggi di testo normale inviati come HTTP POST.
    • XMPP: non supportato.
  • Invio downstream multicast a più token di registrazione.
    • HTTP: supportato nel formato di messaggio JSON.
    • XMPP: non supportato.

Implementazione del protocollo del server HTTP

Per inviare un messaggio, il server dell'app invia una richiesta POST con un'intestazione HTTP e un corpo HTTP composto da coppie chiave-valore JSON. Per i dettagli sulle opzioni di intestazione e corpo, consulta Creazione di richieste di invio all'app server

Implementazione del protocollo del server XMPP

Il payload JSON per i messaggi FCM è simile al protocollo HTTP, con queste eccezioni:

  • Non c'è supporto per più destinatari.
  • FCM aggiunge il campo message_id , che è obbligatorio. Questo ID identifica in modo univoco il messaggio in una connessione XMPP. L'ACK o il NACK di FCM utilizza message_id per identificare un messaggio inviato dai server delle applicazioni a FCM. Pertanto, è importante che questo message_id non solo sia univoco (per ID mittente ), ma sia sempre presente.
  • XMPP utilizza la chiave del server per autorizzare una connessione permanente a FCM. Vedere Autorizzare le richieste di invio per ulteriori informazioni.

Oltre ai normali messaggi FCM, vengono inviati messaggi di controllo, indicati dal campo message_type nell'oggetto JSON. Il valore può essere 'ack' o 'nack' o 'control' (vedere i formati di seguito). Qualsiasi messaggio FCM con un message_type sconosciuto può essere ignorato dal tuo server.

Per ogni messaggio del dispositivo che il server dell'app riceve da FCM, deve inviare un messaggio ACK. Non ha mai bisogno di inviare un messaggio NACK. Se non invii un ACK per un messaggio, FCM lo invia di nuovo la prossima volta che viene stabilita una nuova connessione XMPP, a meno che il messaggio non scada prima.

FCM invia anche un ACK o un NACK per ogni messaggio da server a dispositivo. Se non ricevi nessuno dei due, significa che la connessione TCP è stata chiusa nel mezzo dell'operazione e il tuo server deve inviare nuovamente i messaggi. Vedere Controllo del flusso per i dettagli.

Vedere Protocol Reference per un elenco di tutti i parametri del messaggio.

Formato richiesta

Messaggio con payload: messaggio di notifica

Ecco una stanza XMPP per un messaggio di notifica:

<message id="">
  <gcm xmlns="google:mobile:data">
  {
     "to":"REGISTRATION_ID",  // "to" replaces "registration_ids"
     "notification": {
        "title": "Portugal vs. Denmark”,
        "body”: "5 to 1”
      },
      "time_to_live":"600"
  }
  </gcm>
</message>

Messaggio con payload: messaggio di dati

Ecco una stanza XMPP contenente il messaggio JSON da un server delle applicazioni a FCM:

<message id="">
  <gcm xmlns="google:mobile:data">
  {
      "to":"REGISTRATION_ID",  // "to" replaces "registration_ids"
      "message_id":"m-1366082849205" // new required field
      "data":
      {
          "hello":"world",
      }
      "time_to_live":"600",
  }
  </gcm>
</message>

Formato della risposta

Una risposta FCM può avere tre forme possibili. Il primo è un normale messaggio 'ack'. Ma quando la risposta contiene un errore, ci sono 2 diverse forme che il messaggio può assumere, descritte di seguito.

messaggio di conferma

Ecco una stanza XMPP contenente il messaggio ACK/NACK da FCM al server delle applicazioni:

<message id="">
  <gcm xmlns="google:mobile:data">
  {
      "from":"REGID",
      "message_id":"m-1366082849205"
      "message_type":"ack"
  }
  </gcm>
</message>

Messaggio NACK

Un errore NACK è un normale messaggio XMPP in cui il messaggio di stato message_type è "nack". Un messaggio NACK contiene:

  • Un codice di errore NACK.
  • Una descrizione dell'errore NACK.

Di seguito sono riportati alcuni esempi.

Registrazione errata:

<message>
  <gcm xmlns="google:mobile:data">
  {
    "message_type":"nack",
    "message_id":"msgId1",
    "from":"SomeInvalidRegistrationToken",
    "error":"BAD_REGISTRATION",
    "error_description":"Invalid token on 'to' field: SomeInvalidRegistrationId"
  }
  </gcm>
</message>

JSON non valido:

<message>
 <gcm xmlns="google:mobile:data">
 {
   "message_type":"nack",
   "message_id":"msgId1",
   "from":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
   "error":"INVALID_JSON",
   "error_description":"InvalidJson: JSON_TYPE_ERROR : Field \"time_to_live\" must be a JSON java.lang.Number: abc"
 }
 </gcm>
</message>

Frequenza messaggi dispositivo superata:

<message id="...">
  <gcm xmlns="google:mobile:data">
  {
    "message_type":"nack",
    "message_id":"msgId1",
    "from":"REGID",
    "error":"DEVICE_MESSAGE_RATE_EXCEEDED",
    "error_description":"Downstream message rate exceeded for this registration id"
  }
  </gcm>
</message>

Vedere il riferimento al server per un elenco completo dei codici di errore NACK. Se non diversamente indicato, un messaggio NACKed non dovrebbe essere ritentato. I codici di errore NACK imprevisti devono essere trattati allo stesso modo di INTERNAL_SERVER_ERROR .

Errore di strofa

È inoltre possibile ottenere un errore di stanza in alcuni casi. Un errore di stanza contiene:

  • Codice di errore della strofa.
  • Descrizione dell'errore della stanza (testo libero).

Per esempio:

<message id="3" type="error" to="123456789@fcm.googleapis.com/ABC">
  <gcm xmlns="google:mobile:data">
     {"random": "text"}
  </gcm>
  <error code="400" type="modify">
    <bad-request xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
    <text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">
      InvalidJson: JSON_PARSING_ERROR : Missing Required Field: message_id\n
    </text>
  </error>
</message>

Messaggi di controllo

Periodicamente, FCM deve chiudere una connessione per eseguire il bilanciamento del carico. Prima di chiudere la connessione, FCM invia un messaggio CONNECTION_DRAINING per indicare che la connessione è stata scaricata e verrà chiusa a breve. "Drenaggio" si riferisce all'interruzione del flusso di messaggi che entrano in una connessione, ma consente a tutto ciò che è già nella pipeline di continuare. Quando ricevi un messaggio CONNECTION_DRAINING , dovresti iniziare immediatamente a inviare messaggi a un'altra connessione FCM, aprendo una nuova connessione se necessario. Dovresti, tuttavia, mantenere aperta la connessione originale e continuare a ricevere i messaggi che potrebbero arrivare attraverso la connessione (e a confermarli): FCM gestisce l'avvio di una chiusura della connessione quando è pronta.

Il messaggio CONNECTION_DRAINING ha il seguente aspetto:

<message>
  <data:gcm xmlns:data="google:mobile:data">
  {
    "message_type":"control"
    "control_type":"CONNECTION_DRAINING"
  }
  </data:gcm>
</message>

CONNECTION_DRAINING è attualmente l'unico control_type supportato.

Controllo del flusso

Ogni messaggio inviato a FCM riceve una risposta ACK o NACK. I messaggi che non hanno ricevuto una di queste risposte sono considerati in sospeso. Se il conteggio dei messaggi in attesa raggiunge 100, il server dell'app dovrebbe interrompere l'invio di nuovi messaggi e attendere che FCM riconosca alcuni dei messaggi in attesa esistenti, come illustrato nella figura 1:

Diagramma dettagliato del flusso di controllo tra FCM e l'app server

Figura 1. Flusso messaggio/riconoscimento.

Al contrario, per evitare di sovraccaricare l'app server, FCM interrompe l'invio se ci sono troppi messaggi non confermati. Pertanto, l'app server deve "ACK" messaggi a monte, ricevuti dall'applicazione client tramite FCM, il più presto possibile per mantenere un flusso costante di messaggi in arrivo. Il suddetto limite di messaggi in attesa non si applica a questi ACK. Anche se il conteggio dei messaggi in attesa raggiunge 100, il server app dovrebbe continuare a inviare ACK per i messaggi ricevuti da FCM per evitare di bloccare la consegna di nuovi messaggi upstream.

Gli ACK sono validi solo nel contesto di una connessione. Se la connessione viene chiusa prima che un messaggio possa essere ACKed, il server dell'app deve attendere che FCM invii nuovamente il messaggio upstream prima di ACKing di nuovo. Allo stesso modo, tutti i messaggi pendenti per i quali non è stato ricevuto un ACK/NACK da FCM prima della chiusura della connessione devono essere inviati nuovamente.