Se utilizzi le API FCM per creare richieste di invio a livello di programmazione, potresti scoprire che, nel tempo, sprechi risorse inviando messaggi a dispositivi inattivi con registrazioni obsolete. Questa situazione può influire sui dati di consegna dei messaggi riportati nella console Firebase o sui dati esportati in BigQuery, mostrando un calo drastico (ma non effettivamente valido) dei tassi di consegna. Questa guida illustra alcune misure che puoi adottare per garantire un targeting efficiente dei messaggi e report di consegna validi.
Registrazioni obsolete e scadute
Le registrazioni obsolete sono associate a dispositivi inattivi che non si sono connessi a FCM da più di un mese. Con il passare del tempo, è sempre meno probabile che il dispositivo si connetta di nuovo a FCM È improbabile che gli invii di messaggi e le distribuzioni di argomenti per queste registrazioni obsolete vengano mai consegnati.
Esistono diversi motivi per cui una registrazione può diventare obsoleta. Ad esempio, il dispositivo a cui è associata la registrazione potrebbe essere smarrito, distrutto o messo in magazzino e dimenticato.
Per Android, quando una registrazione è inattiva da 270 giorni, FCM la considera scaduta ed esegue la garbage collection. Una volta scaduta una registrazione, FCM la contrassegna come non valida e rifiuta gli invii. Tieni presente che gli ID di installazione Firebase (FID) sono gestiti da Firebase Installations service (FIS), non da FCM. Nel raro caso in cui un dispositivo si connetta di nuovo e l'app venga aperta dopo che è stata eseguita la garbage collection della sua registrazione, l'app client si registra di nuovo con FCM utilizzando l'FID recuperato da FIS. Tieni presente che l'FID potrebbe cambiare; per maggiori dettagli su quando vengono riemessi gli FID, consulta Gestire le installazioni Firebase.
Per altre piattaforme come iOS, FCM si basa sul servizio push sottostante (ad es. APNs), che non ha la stessa scadenza basata sull'inattività di 270 giorni. Ti consigliamo di mantenere in modo proattivo l'aggiornamento della registrazione e di rimuovere le registrazioni obsolete.
Best practice di base
Esistono alcune pratiche fondamentali che devi seguire in qualsiasi app che utilizzi FCM API per creare richieste di invio a livello di programmazione. Le principali best practice sono:
- Recupera gli ID di installazione Firebase (FID) da FCM e memorizzali sul server dell'app. Un ruolo importante del server è tenere traccia dell'FID registrato di ogni client e mantenere un elenco aggiornato degli FID attivi. Ti consigliamo vivamente di implementare un timestamp di registrazione nel database e di aggiornarlo ogni volta che viene caricata una registrazione.
- Mantieni l'aggiornamento della registrazione e rimuovi le registrazioni obsolete. Oltre a rimuovere le registrazioni che FCM non considera più valide, potresti monitorare altri segnali che indicano che le registrazioni sono diventate obsolete e rimuoverle in modo proattivo. Questa guida illustra alcune opzioni per raggiungere questo obiettivo.
Recuperare e memorizzare gli ID di installazione Firebase
Al primo avvio dell'app, l'FCM SDK registra l'istanza dell'app con FCM e restituisce un ID di installazione Firebase (FID). Questo è l'identificatore che devi includere nelle richieste di invio mirate dall'API o utilizzare per gli abbonamenti agli argomenti.
Ti consigliamo vivamente di salvare l'FID 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 FCM backend.
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
onRegistered()callback viene richiamato regolarmente durante le sincronizzazioni di routine all'avvio dell'app, nonché quando si verificano modifiche dell'FID. Implementa semplicemente questo callback per caricare l'FID sul server e salvare il timestamp corrente. - Quando l'inizializzazione automatica è disattivata: Il
onRegistered()callback non viene richiamato automaticamente all'avvio. Per monitorare le registrazioni e mantenerle aggiornate, chiamaregister()all'avvio dell'app, ad esempio su Android, in `onCreate()` dell'attività principaleonCreate(). Una chiamata riuscita attiva la FCM registrazione procedura utilizzando l'FID e lo invia alonRegistered()callback, consentendo all'app di caricare l'FID e aggiornare il timestamp su server.
Esempio: memorizzare FID e timestamp in Cloud Firestore
Ad esempio, puoi utilizzare Cloud Firestore per memorizzare gli FID 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 di installazione Firebase viene registrato o aggiornato correttamente, viene richiamato il
onRegistered()
callback. Devi implementare questo callback per caricare l'FID 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 consegna dell'FID
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 l'aggiornamento della registrazione e rimuovere le registrazioni obsolete
Determinare se una registrazione è aggiornata o obsoleta non è sempre semplice. Per coprire tutti i casi, devi adottare una soglia per considerare le registrazioni obsolete. Per impostazione predefinita, FCM considera una registrazione obsoleta se l'istanza dell'app non è stata connessa per un mese. È probabile che qualsiasi registrazione precedente a un mese sia un dispositivo inattivo; in caso contrario, un dispositivo attivo avrebbe aggiornato la registrazione.
A seconda del caso d'uso, un mese potrebbe essere troppo breve o troppo lungo, quindi spetta a te determinare i criteri più adatti alle tue esigenze.
Rilevare risposte non valide dal backend FCM
Assicurati di rilevare le risposte non valide da FCM e di rispondere eliminando dal sistema tutte le registrazioni note per essere non valide o scadute. Con l'API HTTP v1, questi messaggi di errore potrebbero indicare che la 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, perché 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 devi monitorare il mancato aggiornamento in modo più accurato in base alle tue definizioni, puoi rimuovere in modo proattivo le registrazioni obsolete.
Aggiornare regolarmente le registrazioni
Indipendentemente dal fatto che le registrazioni siano basate su FID o token di registrazione precedenti, il server deve sempre aggiornare il timestamp di registrazione nel database a ogni richiesta di caricamento. Questo timestamp funge da segnale per l'installazione dell'app, indicando che il client ha aperto correttamente l'app e si è sincronizzato con il FCM backend. A seconda delle API che utilizzi, implementa la strategia appropriata:
Le API ID di 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
si occupa automaticamente degli aggiornamenti durante l'inizializzazione automatica, fornendo regolarmente
l'FID corrente corretto al
onRegistered()
callback 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 memorizzare gli ID di installazione Firebase :
- Inizializzazione automatica attivata: l'SDK garantisce automaticamente che l'ultimo FID venga inviato al 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()) per forzare la sequenza di registrazione e attivare la consegna dell'FID a tuoonRegistered()callback.
Queste strategie garantiscono che il server abbia sempre l'ultimo FID attivo e possa recuperare automaticamente i caricamenti non riusciti, rendendo l'applicazione altamente resiliente.
Le API token di registrazione obsolete
Se utilizzi i 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:
- Aggiungere 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) e quindi inviare il token corrente al server dell'app per l'archiviazione (con un timestamp). Potrebbe trattarsi di un job mensile configurato per coprire tutti i client o i token. - Aggiungere 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 precedenti utilizzando WorkManager, consulta Gestire i token di 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 offre un buon equilibrio tra l'impatto sulla batteria e il rilevamento dei token di registrazione inattivi. Eseguendo questo aggiornamento, ti assicuri anche che qualsiasi dispositivo che diventa inattivo aggiorni la registrazione quando torna attivo. Non è utile eseguire l'aggiornamento con una frequenza superiore a quella settimanale.
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, puoi
implementare Cloud Functions for Firebase per eseguire un controllo giornaliero per assicurarti che il
timestamp rientri in un periodo della finestra di mancato aggiornamento 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 delle registrazioni obsolete agli argomenti
Se utilizzi gli argomenti, potresti anche voler annullare l'iscrizione delle registrazioni inattive agli argomenti a cui sono abbonate. Questa procedura prevede due passaggi:
- L'app deve riabbonarsi agli argomenti ogni volta che l'ID di 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 la tua finestra di obsolescenza), devi annullare l'iscrizione agli argomenti utilizzando l'SDK Admin Firebase per eliminare il mapping ID di installazione Firebase-argomento dal FCM backend.
Il vantaggio di questi due passaggi è che le distribuzioni avvengono più rapidamente perché ci sono meno registrazioni obsolete da distribuire e le istanze dell'app obsolete si riabbonano automaticamente una volta che sono di nuovo attive.
Misurare il successo della consegna
Per ottenere un quadro più preciso della consegna dei messaggi, è consigliabile inviare messaggi solo alle istanze dell'app utilizzate attivamente. Questo è particolarmente importante se invii regolarmente messaggi ad argomenti con un numero elevato di abbonati; se una parte di questi abbonati è in realtà inattiva, l'impatto sulle statistiche di consegna può essere significativo nel tempo.
Prima di indirizzare i messaggi a un'istanza dell'app, considera quanto segue:
- Google Analytics, i dati acquisiti in BigQuery o altri segnali di monitoraggio indicano che la registrazione è attiva?
- I tentativi di consegna precedenti non sono riusciti in modo coerente per un periodo di tempo?
- L'ID di installazione Firebase è stato aggiornato sui server nell'ultimo mese?
- Per i dispositivi Android, l'API dati FCM segnala una percentuale elevata di errori di consegna dei messaggi a causa di
droppedDeviceInactive?
Per ulteriori informazioni sulla consegna, consulta Informazioni sulla consegna dei messaggi.