Join us for Firebase Summit on November 10, 2021. Tune in to learn how Firebase can help you accelerate app development, release with confidence, and scale with ease. Register

Il tuo ambiente server e FCM

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

  • Il backend FCM fornito da Google.
  • Il server app o altro ambiente di server di fiducia in cui le corse di logica server, ad esempio le funzioni cloud per Firebase o in altri ambienti cloud gestiti da Google.

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

Requisiti per l'ambiente del server affidabile

L'ambiente del server dell'app deve soddisfare i seguenti criteri:

  • In grado di inviare richieste di messaggi correttamente formattate al backend FCM.
  • In grado di gestire le richieste e inviare di nuovo utilizzando esponenziale di back-off.
  • 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 inviato (il backend HTTP FCM genera ID messaggio e li restituisce nella risposta). Gli ID dei messaggi XMPP devono essere univoci per ID mittente.

Scelta di un'opzione server

Avrete bisogno di decidere su un modo di interagire con i server FCM: sia utilizzando il Firebase Admin SDK o protocolli prime. A causa del suo supporto nei linguaggi di programmazione più diffusi e dei suoi metodi convenienti per la gestione dell'autenticazione e dell'autorizzazione, Firebase Admin SDK è il metodo consigliato.

Le opzioni per l'interazione con i server FCM includono quanto segue:
  • Il Firebase Admin SDK, che ha il supporto per nodo , Java , Python , C # , e Go .
  • L' FCM HTTP API v1 , che è la più aggiornata delle opzioni di protocollo, con l'autorizzazione più sicuri e flessibili funzionalità di messaggistica cross-platform (la Firebase Admin SDK è basato su questo protocollo e fornisce tutti i suoi vantaggi intrinseci).
  • L'eredità HTTP protocollo.
  • Il XMPP protocollo del server. Si noti che se si desidera utilizzare la messaggistica upstream dalle applicazioni client, è necessario utilizzare XMPP.

SDK di amministrazione Firebase per FCM

L'API Admin FCM gestisce l'autenticazione con il backend e facilita l'invio di messaggi e la gestione degli abbonamenti agli argomenti. Con Firebase Admin SDK, puoi:

  • Invia messaggi a singoli dispositivi
  • Invia messaggi ad argomenti e condizioni che corrispondono a uno o più argomenti.
  • Iscriviti e annulla l'iscrizione ai 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 impostare la Firebase Admin SDK, vedere Aggiungere il Firebase Admin SDK al server . Se si dispone già di un progetto Firebase, iniziare con Aggiungere l'SDK . Poi, una volta installato il Firebase Admin SDK, è possibile iniziare a scrivere logica per le richieste di compilazione di invio .

Protocolli server FCM

Attualmente FCM fornisce questi protocolli server non elaborati:

Il tuo app server può utilizzare questi protocolli separatamente o in tandem. Poiché è il più aggiornato e il più flessibile per l'invio di messaggi a più piattaforme, l'API HTTP v1 di FCM è 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 upstream/downstream
    • 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 app inviano messaggi come richieste HTTP POST e attendono una risposta. Questo meccanismo è sincrono e impedisce al mittente di inviare un altro messaggio fino alla ricezione della risposta.
    • XMPP: asincrono. I server delle app inviano/ricevono messaggi a/da tutti i loro dispositivi alla massima velocità di linea su connessioni XMPP persistenti. Il server di connessione XMPP invia notifiche di riconoscimento o di errore (sotto forma di messaggi XMPP codificati JSON ACK e NACK speciali) in modo asincrono.
  • JSON
    • HTTP: messaggi JSON inviati come HTTP POST.
    • XMPP: messaggi JSON incapsulati in messaggi XMPP.
  • Testo normale
    • HTTP: messaggi di testo semplice inviati come HTTP POST.
    • XMPP: non supportato.
  • Invio multicast downstream a più token di registrazione.
    • HTTP: supportato in formato 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 il corpo, vedi Costruire App Server richieste di trasmissione

Implementazione del protocollo 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 è richiesto. Questo ID identifica in modo univoco il messaggio in una connessione XMPP. L'ACK o NACK dalla FCM utilizza il message_id per identificare un messaggio inviato dai server di applicazioni a FCM. Pertanto, è importante che questo message_id non solo essere univoco (per ID del mittente ), ma sempre presente.
  • XMPP utilizza la chiave del server per autorizzare una connessione permanente a FCM. Vedere Autorizza Invia le richieste per ulteriori informazioni.

Oltre ai messaggi FCM regolari, messaggi di controllo sono inviati, indicata dal message_type campo nell'oggetto JSON. Il valore può essere 'ack' o 'nack' o 'control' (vedi formati sotto). Qualsiasi messaggio FCM con uno sconosciuto message_type può essere ignorato dal server.

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

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

Vedere il riferimento Protocollo per un elenco di tutti i parametri del messaggio.

Formato della 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 carico utile — messaggio di dati

Ecco una stanza XMPP contenente il messaggio JSON da un server app 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 di risposta

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

messaggio di ACK

Ecco una stanza XMPP contenente il messaggio ACK/NACK da FCM all'app server:

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

NACK messaggio

Errore di un NACK è un messaggio normale XMPP in cui il message_type messaggio di stato è "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>

Velocità 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 Server per un elenco completo dei codici di errore NACK. Se non diversamente indicato, un messaggio NACKed non deve essere ritentato. Inaspettati codici di errore NACK devono essere trattate come INTERNAL_SERVER_ERROR .

Errore di strofa

Puoi anche ottenere un errore di stanza in alcuni casi. Un errore di stanza contiene:

  • Codice di errore della stanza.
  • 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 manda un CONNECTION_DRAINING messaggio per indicare che la connessione venga scaricata e verrà chiuso presto. "Drenaggio" si riferisce all'interruzione del flusso di messaggi in arrivo in una connessione, ma consentendo a ciò che è già nella pipeline di continuare. Quando si riceve un CONNECTION_DRAINING messaggio, si dovrebbe iniziare immediatamente l'invio di messaggi a un altro collegamento FCM, l'apertura di una nuova connessione, se necessario. Dovresti, tuttavia, mantenere la connessione originale aperta e continuare a ricevere i messaggi che potrebbero arrivare sulla connessione (e ad eseguirne il ACK): FCM gestisce l'avvio di una chiusura della connessione quando è pronta.

Il CONNECTION_DRAINING messaggio simile a questo:

<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 sospeso raggiunge 100, il server dell'app dovrebbe interrompere l'invio di nuovi messaggi e attendere che FCM riconosca alcuni dei messaggi in sospeso esistenti, come illustrato nella figura 1:

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

Figura 1. Messaggio / ack flusso.

Al contrario, per evitare di sovraccaricare il server dell'app, FCM interrompe l'invio se sono presenti troppi messaggi non riconosciuti. Pertanto, l'app server dovrebbe "ACK" i messaggi upstream, ricevuti dall'applicazione client tramite FCM, il prima possibile per mantenere un flusso costante di messaggi in arrivo. Il suddetto limite di messaggi in sospeso non si applica a questi ACK. Anche se il conteggio dei messaggi in sospeso raggiunge 100, il server dell'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 ACK, il server dell'app dovrebbe attendere che FCM invii nuovamente il messaggio upstream prima di riattivarlo. Allo stesso modo, tutti i messaggi in sospeso per i quali non è stato ricevuto un ACK/NACK da FCM prima della chiusura della connessione dovrebbero essere inviati nuovamente.