Se utilizzi le FCM API per creare richieste di invio in modo programmatico, potresti scoprire che, nel tempo, sprechi risorse inviando messaggi a dispositivi inattivi con token di registrazione obsoleti. 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.
Token di registrazione obsoleti e scaduti
I token di registrazione obsoleti sono token associati 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 questi token obsoleti vengano mai consegnati.
Esistono diversi motivi per cui un token può diventare obsoleto. Ad esempio, il dispositivo a cui è associato il token potrebbe essere smarrito, distrutto o messo in magazzino e dimenticato.
Per Android, quando i token obsoleti raggiungono 270 giorni di inattività, FCM li considera scaduti. Una volta scaduto un token, FCM lo contrassegna come non valido e rifiuta gli invii. Tuttavia, FCM emette un nuovo token per l'istanza dell'app nel raro caso in cui il dispositivo si connetta di nuovo e l'app venga aperta.
Per altre piattaforme come iOS, FCM si basa sul servizio push sottostante (ad es. APNs), che non ha la stessa scadenza del token basata sull'inattività di 270 giorni. Ti consigliamo quindi di mantenere in modo proattivo la freschezza dei token e di rimuovere i token di registrazione obsoleti.
Best practice di base
Esistono alcune pratiche fondamentali che devi seguire in qualsiasi app che utilizza FCM API per creare richieste di invio in modo programmatico. Le principali best practice sono:
- Recupera i token di registrazione da FCM e memorizzali sul tuo server. Un ruolo importante del server è tenere traccia del token di ogni client e mantenere un elenco aggiornato dei token attivi. Ti consigliamo vivamente di implementare un timestamp del token nel codice e nei server e di aggiornarlo a intervalli regolari.
- Mantieni la freschezza dei token e rimuovi i token obsoleti. Oltre a rimuovere i token che FCM non considera più validi, potresti voler monitorare altri segnali che indicano che i token sono diventati obsoleti e rimuoverli in modo proattivo. Questa guida illustra alcune opzioni per raggiungere questo obiettivo.
Recuperare e memorizzare i token di registrazione
Al primo avvio dell'app, l'FCM SDK genera un token di registrazione per l'istanza dell'app client. Questo è il token che devi includere nelle richieste di invio mirate dall'API o aggiungere agli abbonamenti agli argomenti per il targeting degli argomenti.
Ti consigliamo vivamente di recuperare questo token al primo avvio e di salvarlo sul server dell'app insieme a un timestamp. Questo timestamp deve essere implementato dal codice e dai server, in quanto non viene fornito dagli FCM SDK.
Inoltre, è importante salvare il token sul server e aggiornare il timestamp ogni volta che cambia, ad esempio quando:
- L'app viene ripristinata su un nuovo dispositivo
- L'utente disinstalla o reinstalla l'app
- L'utente cancella i dati dell'app
- L'app torna attiva dopo che FCM ha fatto scadere il token esistente
Esempio: memorizzare token e timestamp in Cloud Firestore
Ad esempio, puoi utilizzare Cloud Firestore per memorizzare i token in una raccolta denominata fcmTokens. Ogni ID documento nella raccolta corrisponde a un ID utente e il documento memorizza il token di registrazione corrente e il timestamp dell'ultimo aggiornamento. Utilizza la funzione set come mostrato in questo esempio Kotlin:
/**
* Persist token to third-party servers.
*
* Modify this method to associate the user's FCM registration token with any server-side account
* maintained by your application.
*
* @param token The new token.
*/
private fun sendTokenToServer(token: String?) {
// If you're running your own server, call API to send token and today's date for the user
// Example shown below with Firestore
// Add token and timestamp to Firestore for this user
val deviceToken = hashMapOf(
"token" to token,
"timestamp" to FieldValue.serverTimestamp(),
)
// Get user ID from Firebase Auth or your own server
Firebase.firestore.collection("fcmTokens").document("myuserid")
.set(deviceToken)
}
Ogni volta che viene recuperato un token, viene memorizzato in Cloud Firestore chiamando
sendTokenToServer:
/**
* Called if the FCM registration token is updated. This may occur if the security of
* the previous token had been compromised. Note that this is called when the
* FCM registration token is initially generated so this is where you would retrieve the token.
*/
override fun onNewToken(token: String) {
Log.d(TAG, "Refreshed token: $token")
// If you want to send messages to this application instance or
// manage this apps subscriptions on the server side, send the
// FCM registration token to your app server.
sendTokenToServer(token)
}
var token = Firebase.messaging.token.await()
// Check whether the retrieved token matches the one on your server for this user's device
val preferences = this.getPreferences(Context.MODE_PRIVATE)
val tokenStored = preferences.getString("deviceToken", "")
lifecycleScope.launch {
if (tokenStored == "" || tokenStored != token)
{
// If you have your own server, call API to send the above token and Date() for this user's device
// Example shown below with Firestore
// Add token and timestamp to Firestore for this user
val deviceToken = hashMapOf(
"token" to token,
"timestamp" to FieldValue.serverTimestamp(),
)
// Get user ID from Firebase Auth or your own server
Firebase.firestore.collection("fcmTokens").document("myuserid")
.set(deviceToken).await()
}
}
Mantenere la freschezza dei token e rimuovere i token obsoleti
Determinare se un token è recente o obsoleto non è sempre semplice. Per coprire tutti i casi, devi adottare una soglia per quando consideri i token obsoleti. Per impostazione predefinita, FCM considera un token obsoleto se l'istanza dell'app non si è connessa per un mese. È probabile che qualsiasi token più vecchio di un mese sia un dispositivo inattivo; in caso contrario, un dispositivo attivo avrebbe aggiornato il token.
A seconda del caso d'uso, un mese potrebbe essere troppo breve o troppo lungo, quindi spetta a te determinare i criteri più adatti.
Rilevare le risposte di token non validi dal FCM backend
Assicurati di rilevare le risposte di token non validi da FCM e di rispondere eliminando dal sistema tutti i token di registrazione noti per essere non validi o scaduti. Con l'API HTTP v1, questi messaggi di errore possono indicare che la richiesta di invio ha come target token non validi o scaduti:
UNREGISTERED(HTTP 404)INVALID_ARGUMENT(HTTP 400)
Se sei certo che il payload del messaggio sia valido e ricevi una di queste risposte per un token di destinazione, puoi eliminare in sicurezza il record di questo token, perché non sarà mai più valido. Ad esempio, per eliminare i token non validi da Cloud Firestore, puoi eseguire il deployment ed eseguire una funzione come la seguente:
// Registration token comes from the client FCM SDKs
const registrationToken = 'YOUR_REGISTRATION_TOKEN';
const message = {
data: {
// Information you want to send inside of notification
},
token: registrationToken
};
// Send message to device with provided registration token
getMessaging().send(message)
.then((response) => {
// Response is a message ID string.
})
.catch((error) => {
// Delete token 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
token for the user
// Example shown below with Firestore
// Get user ID from Firebase Auth or your own server
Firebase.firestore.collection("fcmTokens").document(user.uid).delete()
}
});
FCM restituisce una risposta di token non valido se un token per un dispositivo Android è scaduto dopo 270 giorni di inattività o se un client ha annullato esplicitamente la registrazione. Se devi monitorare con maggiore precisione il mancato aggiornamento in base alle tue definizioni, puoi rimuovere in modo proattivo i token di registrazione obsoleti.
Aggiornare regolarmente i token
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 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. In questo modo, ti assicuri anche che qualsiasi dispositivo che diventa inattivo aggiorni la registrazione quando torna attivo. Non è utile eseguire l'aggiornamento più spesso di una volta alla settimana.
Rimuovere i token di registrazione obsoleti
Prima di inviare messaggi a un dispositivo, assicurati che il timestamp del token di 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 di mancato aggiornamento definito, ad esempio const
EXPIRATION_TIME = 1000 * 60 * 60 * 24 * 30; e quindi rimuovere i token obsoleti:
exports.pruneTokens = functions.pubsub.schedule('every 24 hours').onRun(async (context) => {
// Get all documents where the timestamp exceeds is not within the past month
const staleTokensResult = await admin.firestore().collection('fcmTokens')
.where("timestamp", "<", Date.now() - EXPIRATION_TIME)
.get();
// Delete devices with stale tokens
staleTokensResult.forEach(function(doc) { doc.ref.delete(); });
});
Annullare l'iscrizione dei token obsoleti agli argomenti
Se utilizzi gli argomenti, potresti anche annullare la registrazione dei token obsoleti agli argomenti a cui sono iscritti. Questa operazione prevede due passaggi:
- L'app deve abbonarsi di nuovo agli argomenti una volta al mese e ogni volta che il token di registrazione cambia. Si tratta di una soluzione di auto-riparazione, in cui gli abbonamenti vengono visualizzati 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 Firebase Admin per eliminare il mapping da token ad argomento dal backend FCM.
Il vantaggio di questi due passaggi è che i fan-out avvengono più rapidamente perché ci sono meno token inattivi da distribuire e le istanze dell'app inattive si riabboneranno automaticamente una volta che saranno di nuovo attive.
Misurare il successo della consegna
Per ottenere un'immagine più accurata 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 è effettivamente inattiva, l'impatto sulle statistiche di consegna può essere significativo nel tempo.
Prima di scegliere come target i messaggi per un token, considera:
- Google Analytics, i dati acquisiti in BigQuery o altri segnali di monitoraggio indicano che il token è attivo?
- I tentativi di consegna precedenti non sono riusciti in modo coerente per un periodo di tempo?
- Il token di registrazione è 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 la sezione Comprendere la consegna dei messaggi.