Google is committed to advancing racial equity for Black communities. See how.
Questa pagina è stata tradotta dall'API Cloud Translation.
Switch to English

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 delle app o un altro ambiente server attendibile in cui viene eseguita la logica del server, come Cloud Functions per Firebase o altri ambienti cloud gestiti da Google.

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

Requisiti per l'ambiente del server attendibile

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

  • In grado di inviare richieste di messaggi formattati correttamente al back-end FCM.
  • In grado di gestire le richieste e inviarle di nuovo 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 dei messaggi XMPP devono essere univoci per ID mittente.

Scegliere un'opzione del server

Dovrai decidere un modo per interagire con i server FCM: utilizzando Firebase Admin SDK o i protocolli non elaborati. A causa del suo supporto nei più diffusi linguaggi di programmazione 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:

Firebase Admin SDK 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 istruzioni di condizione che corrispondono a uno o più argomenti.
  • Sottoscrivi e annulla la sottoscrizione di dispositivi ae da argomenti
  • Costruisci payload di messaggi su misura per diverse piattaforme di destinazione

Admin Node.js SDK fornisce metodi per inviare messaggi a gruppi di dispositivi.

Per configurare Firebase Admin SDK, vedi Aggiungere Firebase Admin SDK al tuo server . Se hai già un progetto Firebase, inizia con Aggiungi l'SDK . Quindi, una volta installato Firebase Admin SDK, puoi iniziare a scrivere la logica per creare richieste di invio .

Protocolli server FCM

Attualmente FCM fornisce questi protocolli server non elaborati:

Il tuo server app può utilizzare questi protocolli separatamente o in tandem. Poiché è il più aggiornato e flessibile per l'invio di messaggi a più piattaforme, l'API FCM HTTP v1 è consigliata laddove 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 a quando non riceve la risposta.
    • XMPP: asincrono. I server delle app inviano / ricevono messaggi a / da tutti i loro dispositivi alla massima velocità di linea tramite connessioni XMPP persistenti. Il server di connessione XMPP invia notifiche di riconoscimento o di errore (sotto forma di messaggi XMPP speciali 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 normale
    • 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 app invia una richiesta POST con un'intestazione HTTP e un corpo HTTP composto da coppie di valori chiave JSON. Per i dettagli sulle opzioni di intestazione e corpo, vedere Compilazione di richieste di invio del server app

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 è obbligatorio. Questo ID identifica in modo univoco il messaggio in una connessione XMPP. ACK o NACK da FCM utilizza message_id per identificare un messaggio inviato dai server app a FCM. Pertanto, è importante che questo message_id non sia solo univoco (per ID mittente ), ma sempre presente.
  • XMPP utilizza la chiave del server per autorizzare una connessione persistente 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 ricevuto dal tuo server app da FCM, deve inviare un messaggio ACK. Non è mai necessario 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 nessuno dei due, significa che la connessione TCP è stata chiusa durante l'operazione e il tuo server deve inviare nuovamente i messaggi. Vedere Controllo del flusso per i dettagli.

Consultare il 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 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 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 ACK

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

<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.

Cattiva registrazione:

<message>
  <gcm xmlns="google:mobile:data">
  {
    "message_type":"nack",
    "message_id":"msgId1",
    "from":"SomeInvalidRegistrationId",
    "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 al server per un elenco completo dei codici di errore NACK. Se non diversamente indicato, un messaggio NACKed non deve essere ritentato. I codici di errore NACK imprevisti devono essere trattati come INTERNAL_SERVER_ERROR .

Errore stanza

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

  • Codice di errore stanza.
  • Descrizione errore 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 è in fase di svuotamento e verrà chiusa a breve. "Draining" si riferisce all'interruzione del flusso di messaggi in entrata in una connessione, ma consentendo 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. Tuttavia, dovresti mantenere aperta la connessione originale e continuare a ricevere i messaggi che potrebbero arrivare attraverso la connessione (e ACK): FCM gestisce l'avvio di una chiusura della connessione quando è pronta.

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

Figura 1. Flusso di messaggi / ack.

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 deve continuare a inviare ACK per i messaggi ricevuti da FCM per evitare di bloccare il recapito 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 app deve attendere che FCM invii nuovamente il messaggio upstream prima di ACK di nuovo. 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 di nuovo.