Se utilizzi le API FCM per creare richieste di invio in modo programmatico, potresti notare che, nel tempo, sprechi risorse inviando messaggi a dispositivi inattivi con registrazioni obsolete. Questa situazione può influire sui dati di pubblicazione dei messaggi riportati nella console Firebase o sui dati esportati in BigQuery, che mostrano un calo drastico (ma non valido) dei tassi di pubblicazione. Questa guida illustra alcune misure che puoi adottare per garantire un targeting efficiente dei messaggi e report sulla pubblicazione validi.
Registrazioni obsolete e scadute
Le registrazioni obsolete sono associate a dispositivi inattivi che non si sono connessi a FCM per più di un mese. Con il passare del tempo, la probabilità che il dispositivo si connetta di nuovo a FCM diminuisce sempre di più. È improbabile che gli invii di messaggi e le distribuzioni di argomenti per queste registrazioni obsolete vengano mai recapitati.
Esistono diversi motivi per cui una registrazione può diventare obsoleta. Ad esempio, il dispositivo a cui è associata la registrazione potrebbe essere smarrito, distrutto o riposto in un magazzino e dimenticato.
Per Android, quando una registrazione è inattiva da 270 giorni, FCM la considera scaduta e la raccoglie. Una volta scaduta una registrazione, FCM la contrassegna come non valida e rifiuta gli invii. Tieni presente che gli ID installazione di Firebase (FID) sono gestiti dal servizio Firebase Installations (FIS), non da FCM. Nel raro caso in cui un dispositivo si connetta di nuovo e l'app venga aperta dopo che la sua registrazione è stata sottoposta a garbage collection, l'app client si registra di nuovo con FCM utilizzando l'ID dispositivo recuperato da FIS. Tieni presente che l'ID installazione Firebase potrebbe cambiare. Per informazioni dettagliate su quando vengono riemessi gli ID installazione Firebase, consulta Gestire le installazioni Firebase.
Per altre piattaforme come iOS, FCM si basa sul servizio push sottostante (ad es. APN), che non ha la stessa scadenza basata sull'inattività di 270 giorni. Ti consigliamo di mantenere aggiornata la registrazione e rimuovere le registrazioni obsolete.
Best practice di base
Esistono alcune pratiche fondamentali da seguire in qualsiasi app che utilizzi le API FCM per creare richieste di invio in modo programmatico. Le best practice principali sono:
- Recupera gli ID installazione Firebase (FID) da FCM e archiviali sul server dell'app. Un ruolo importante del server è tenere traccia dell'ID dispositivo registrato di ogni client e mantenere un elenco aggiornato degli ID dispositivo attivi. Ti consigliamo vivamente di implementare un timestamp di registrazione nel tuo database e di aggiornarlo ogni volta che viene caricata una registrazione.
- Mantenere aggiornate le registrazioni e rimuovere quelle obsolete. Oltre a rimuovere le registrazioni che FCM non considera più valide, ti consigliamo di monitorare altri segnali che indicano che le registrazioni sono diventate obsolete e di rimuoverle in modo proattivo. Questa guida illustra alcune delle opzioni a tua disposizione per raggiungere questo obiettivo.
Recuperare e archiviare gli ID installazione Firebase
All'avvio iniziale dell'app, l'SDK FCM registra l'istanza dell'app con FCM e restituisce un ID installazione Firebase (FID). Questo è l'identificatore che devi includere nelle richieste di invio mirato dall'API o utilizzare per gli abbonamenti agli argomenti.
Ti consigliamo vivamente di salvare l'ID funzionalità sul server dell'app insieme a un timestamp ogni volta che viene caricato. Aggiornando il timestamp a ogni richiesta di caricamento, il tuo server sa quando l'istanza dell'app è stata aperta e sincronizzata correttamente con il backend FCM.
A seconda che l'inizializzazione automatica sia attivata o disattivata (incluso il caso in cui non sia supportata), devi gestire la registrazione e gli aggiornamenti nel seguente modo:
- (Consigliato) Quando l'inizializzazione automatica è attivata:l'SDK mantiene automaticamente
aggiornata la registrazione e monitora le modifiche. Il callback
onRegistered()viene richiamato regolarmente durante le sincronizzazioni di routine all'avvio dell'app, nonché quando si verificano modifiche all'ID installazione. Implementa questo callback per caricare l'ID funzionalità sul tuo server e salvare il timestamp corrente. - Quando l'inizializzazione automatica è disattivata: il
callback
onRegistered()non verrà richiamato automaticamente all'avvio. Per monitorare le registrazioni e mantenerle aggiornate, chiamaregister()all'avvio dell'app, ad esempio su Android, nell'onCreate()dell'attività principale. Una chiamata riuscita attiva la procedura di registrazione FCM utilizzando l'ID installazione e lo invia al callbackonRegistered(), consentendo alla tua app di caricare l'ID installazione e aggiornare il timestamp sul tuo server.
Esempio: ID negozio e timestamp in Cloud Firestore
Ad esempio, potresti utilizzare Cloud Firestore per archiviare gli ID istanza in una raccolta denominata
fcmRegistrations. Ogni ID documento nella raccolta corrisponde a un ID utente
e il documento memorizza l'FID corrente e il timestamp dell'ultimo aggiornamento. Utilizza la
funzione set come mostrato in questo esempio Kotlin:
private fun sendRegistrationToServer(installationId: String?) {
// If you're running your own server, call API to send registration details and today's date for the user
// Example shown uses Firestore
// Add FID and timestamp to Firestore for this user
val deviceFid = hashMapOf(
"installationId" to installationId,
"timestamp" to FieldValue.serverTimestamp(),
)
// Get user ID from Firebase Auth or your own server
Firebase.firestore.collection("fcmRegistrations").document("myuserid")
.set(deviceFid)
}
Ogni volta che un ID installazione Firebase viene registrato o aggiornato correttamente, viene richiamato il callback
onRegistered(). Devi implementare questo callback per caricare l'ID fedeltà e
aggiornare il timestamp:
override fun onRegistered(installationId: String) {
Log.d(TAG, "Registered installation ID: $installationId")
// Send the Firebase Installation ID (FID) to your app server. Your app
// server should save the FID and update the timestamp upon receipt.
sendRegistrationToServer(installationId)
}
Per le istanze in cui l'inizializzazione automatica è disattivata, chiama
register()
all'avvio dell'app (ad es. in onCreate()) per attivare il flusso di registrazione e la distribuzione dell'ID client
tramite
onRegistered():
// Trigger manual registration if auto-initialization is turned off.
FirebaseMessaging.getInstance().register()
.addOnCompleteListener(this) { task ->
if (task.isSuccessful) {
// The registration callback onRegistered() will be invoked with the current FID.
} else {
Log.w(TAG, "Failed to register with Firebase Cloud Messaging", task.exception)
}
}
Mantenere aggiornata la registrazione e rimuovere le registrazioni obsolete
Determinare se una registrazione è recente o meno non è sempre semplice. Per coprire tutti i casi, devi adottare una soglia per quando consideri le registrazioni obsolete. Per impostazione predefinita, FCM considera una registrazione obsoleta se l'istanza dell'app non si connette da un mese. Qualsiasi registrazione più vecchia di un mese è probabilmente un dispositivo inattivo; un dispositivo attivo avrebbe altrimenti aggiornato la registrazione.
A seconda del tuo caso d'uso, un mese potrebbe essere troppo breve o troppo lungo, quindi spetta a te determinare i criteri più adatti.
Rileva risposte non valide dal backend FCM
Assicurati di rilevare le risposte non valide da FCM e di rispondere eliminando dal tuo sistema le registrazioni note per essere non valide o scadute. Con l'API HTTP v1, questi messaggi di errore potrebbero indicare che la tua richiesta di invio ha come target registrazioni non valide o scadute:
UNREGISTERED(HTTP 404)INVALID_ARGUMENT(HTTP 400)
Se hai la certezza che il payload del messaggio sia valido e ricevi una di queste risposte per una registrazione mirata, puoi eliminare in sicurezza il record di questa registrazione, poiché non sarà mai più valido. Ad esempio, per eliminare le registrazioni non valide da Cloud Firestore, puoi eseguire il deployment ed eseguire una funzione come la seguente:
// Firebase Installation ID comes from the client FCM SDKs
const firebaseInstallationId = 'YOUR_FIREBASE_INSTALLATION_ID';
const message = {
data: {
// Information you want to send inside of notification
},
fid: firebaseInstallationId
};
// Send message to device with provided Firebase Installation ID
getMessaging().send(message)
.then((response) => {
// Response is a message ID string.
})
.catch((error) => {
// Delete registration for user if error code is UNREGISTERED or INVALID_ARGUMENT.
if (error.errorCode == "messaging/registration-token-not-registered") {
// If you're running your own server, call API to delete the registration for the user
// Example shown uses Firestore
// Get user ID from Firebase Auth or your own server
Firebase.firestore.collection("fcmRegistrations").document(user.uid).delete()
}
});
FCM restituisce una risposta non valida se una registrazione per un dispositivo Android è scaduta dopo 270 giorni di inattività o se un client ha annullato esplicitamente la registrazione. Se hai bisogno di monitorare con maggiore precisione l'obsolescenza in base alle tue definizioni, puoi rimuovere in modo proattivo le registrazioni obsolete.
Aggiornare regolarmente le registrazioni
Indipendentemente dal fatto che le registrazioni si basino su ID istanza o token di registrazione legacy, il server deve sempre aggiornare il timestamp di registrazione nel database a ogni richiesta di caricamento. Questo timestamp funge da indicatore per l'installazione dell'app, comunicando al client che l'app è stata aperta correttamente e sincronizzata con il backend FCM. A seconda delle API che utilizzi, implementa la strategia appropriata:
API ID installazione Firebase (consigliate)
Per le app client che utilizzano le API FID, non è necessario pianificare
job in background periodici nell'app client per recuperare o aggiornare le registrazioni. L'SDK
gestisce automaticamente gli aggiornamenti durante l'inizializzazione automatica, fornendo regolarmente
l'ID dispositivo corrente corretto al tuo
callback onRegistered()
durante le sincronizzazioni di routine all'avvio dell'app.
Per mantenere aggiornato il server, implementa le strategie di caricamento all'avvio descritte in Recuperare e archiviare gli ID installazione Firebase:
- Inizializzazione automatica attivata:l'SDK garantisce automaticamente che l'ultimo FID venga inviato al tuo server durante le sincronizzazioni di routine all'avvio dell'app.
- Inizializzazione automatica disattivata o non supportata:chiama
register()all'avvio dell'app (ad esempio, su Android, inonCreate()dell'attività principale) per forzare la sequenza di registrazione e attivare la distribuzione dell'ID installazione al tuo callbackonRegistered().
Queste strategie garantiscono che il server disponga sempre dell'ultimo FID attivo e possa recuperare automaticamente gli upload non riusciti, rendendo l'applicazione altamente resiliente.
API token di registrazione deprecate
Se utilizzi token di registrazione precedenti, l'SDK client non gestisce automaticamente gli aggiornamenti durante le sincronizzazioni di routine. Pertanto, ti consigliamo di recuperare e aggiornare periodicamente tutti i token di registrazione sul server. Per farlo, devi:
- Aggiungi la logica dell'app nell'app client per recuperare il token corrente utilizzando la chiamata API appropriata (ad esempio
token(completion):per le piattaforme Apple ogetToken()per Android), quindi invia il token corrente al server dell'app per l'archiviazione (con un timestamp). Potrebbe trattarsi di un job mensile configurato per coprire tutti i clienti o i token. - Aggiungi la logica del server per aggiornare il timestamp del token a intervalli regolari, indipendentemente dal fatto che il token sia cambiato o meno.
Per un esempio di logica Android per l'aggiornamento dei token legacy utilizzando WorkManager, consulta Gestione dei token Cloud Messaging sul blog di Firebase.
Qualunque sia il pattern di tempistica che segui, assicurati di aggiornare periodicamente i token. Una frequenza di aggiornamento di una volta al mese rappresenta un buon equilibrio tra l'impatto sulla batteria e il rilevamento dei token di registrazione inattivi. In questo modo, ti assicuri anche che qualsiasi dispositivo che diventa inattivo aggiorni la registrazione quando torna attivo. Non è utile eseguire l'aggiornamento più di una volta alla settimana.
Rimuovere le registrazioni obsolete
Prima di inviare messaggi a un dispositivo, assicurati che il timestamp della registrazione del dispositivo
rientri nel periodo della finestra di obsolescenza. Ad esempio, potresti
implementare Cloud Functions for Firebase per eseguire un controllo giornaliero per assicurarti che
il timestamp rientri in un periodo di obsolescenza definito, ad esempio const
EXPIRATION_TIME = 1000 * 60 * 60 * 24 * 30;, e poi rimuovere le registrazioni
obsolete:
exports.pruneRegistrations = functions.pubsub.schedule('every 24 hours').onRun(async (context) => {
// Get all documents where the timestamp exceeds is not within the past month
const staleRegistrationsResult = await admin.firestore().collection('fcmRegistrations')
.where("timestamp", "<", Date.now() - EXPIRATION_TIME)
.get();
// Delete devices with stale registrations
staleRegistrationsResult.forEach(function(doc) { doc.ref.delete(); });
});
Annullare l'iscrizione di registrazioni obsolete agli argomenti
Se utilizzi gli argomenti, ti consigliamo di annullare l'iscrizione di quelle registrazioni obsolete agli argomenti a cui sono iscritte. che prevede due passaggi:
- La tua app deve iscriversi di nuovo agli argomenti ogni volta che l'ID installazione Firebase (FID) cambia. In questo modo, gli abbonamenti vengono visualizzati di nuovo automaticamente quando un'app torna attiva.
- Se un'istanza dell'app è inattiva per un mese (o per il periodo di inattività che hai impostato), devi annullare la sua iscrizione agli argomenti utilizzando l'SDK Firebase Admin per eliminare la mappatura dell'ID installazione Firebase all'argomento dal backend FCM.
Il vantaggio di questi due passaggi è che i fanout si verificano più rapidamente poiché ci sono meno registrazioni obsolete a cui inviare i fanout e le istanze dell'app obsolete si abboneranno nuovamente in automatico una volta riattivate.
Misurare la riuscita della pubblicazione
Per ottenere un quadro più preciso della distribuzione dei messaggi, è consigliabile inviare messaggi solo alle istanze dell'app utilizzate attivamente. Ciò è particolarmente importante se invii regolarmente messaggi a argomenti con un numero elevato di iscritti; se una parte di questi iscritti è in realtà inattiva, l'impatto sulle statistiche di recapito può essere significativo nel tempo.
Prima di scegliere come target i messaggi per un'istanza dell'app, considera quanto segue:
- Google Analytics, i dati acquisiti in BigQuery o altri indicatori di monitoraggio indicano che la registrazione è attiva?
- I precedenti tentativi di consegna non sono andati a buon fine per un periodo di tempo?
- L'ID installazione Firebase è stato aggiornato sui tuoi server nell'ultimo mese?
- Per i dispositivi Android, l'API FCM Data
segnala una percentuale elevata di errori di recapito dei messaggi a causa di
droppedDeviceInactive?
Per ulteriori informazioni sulla consegna, consulta la sezione Informazioni sulla consegna dei messaggi.