Wenn Sie FCM APIs verwenden, um Sendeanfragen programmatisch zu erstellen, stellen Sie möglicherweise fest, dass Sie mit der Zeit Ressourcen verschwenden, indem Sie Nachrichten an inaktive Geräte mit veralteten Registrierungstokens senden. Diese Situation kann sich auf die in der Firebase-Konsole gemeldeten Daten zur Nachrichtenzustellung oder auf Daten auswirken, die nach BigQuery exportiert werden. Dies kann zu einem drastischen (aber nicht tatsächlich gültigen) Rückgang der Zustellungsraten führen. In diesem Leitfaden werden einige Maßnahmen beschrieben, die Sie ergreifen können, um eine effiziente Nachrichtenausrichtung und eine gültige Zustellungsberichterstattung zu gewährleisten.
Veraltete und abgelaufene Registrierungstokens
Veraltete Registrierungstokens sind Tokens, die mit inaktiven Geräten verknüpft sind, die keine Verbindung zu FCM seit über einem Monat hergestellt haben. Mit der Zeit wird es immer unwahrscheinlicher, dass das Gerät jemals wieder eine Verbindung zu FCM herstellt. Nachrichtensendungen und Topic-Fanouts für diese veralteten Tokens werden wahrscheinlich nie zugestellt.
Es gibt mehrere Gründe, warum ein Token veraltet sein kann. Beispielsweise kann das Gerät, mit dem das Token verknüpft ist, verloren gegangen, zerstört oder eingelagert und vergessen worden sein.
Bei Android werden veraltete Tokens nach 270 Tagen Inaktivität von FCM als abgelaufen betrachtet. Sobald ein Token abläuft, FCM markiert es als ungültig und lehnt Sendungen an dieses Token ab. In dem seltenen Fall, dass das Gerät wieder eine Verbindung herstellt und die App geöffnet wird, gibt FCM jedoch ein neues Token für die App-Instanz aus.
Bei anderen Plattformen wie iOS verwendet FCM den zugrunde liegenden Push-Dienst (z.B. APNs), der nicht denselben Tokenablauf nach 270 Tagen Inaktivität hat. Wir empfehlen daher, die Token proaktiv auf dem neuesten Stand zu halten und veraltete Registrierungstokens zu entfernen.
Grundlegende Best Practices
Es gibt einige grundlegende Best Practices, die Sie in jeder App befolgen sollten, die FCM APIs verwendet, um Sendeanfragen programmatisch zu erstellen. Die wichtigsten Best Practices sind:
- Registrierungstokens von FCM abrufen und auf Ihrem Server speichern. Eine wichtige Aufgabe des Servers besteht darin, das Token jedes Clients zu verfolgen und eine aktualisierte Liste aktiver Tokens zu führen. Wir empfehlen dringend, einen Token-Zeitstempel in Ihrem Code und auf Ihren Servern zu implementieren und diesen Zeitstempel in regelmäßigen Abständen zu aktualisieren.
- Tokens auf dem neuesten Stand halten und veraltete Tokens entfernen. Neben dem Entfernen von Tokens, die FCM von FCM nicht mehr als gültig betrachtet werden, sollten Sie auch andere Anzeichen dafür beobachten, dass Tokens veraltet sind, und sie proaktiv entfernen. In diesem Leitfaden werden einige Optionen beschrieben, wie Sie dies erreichen können.
Registrierungstokens abrufen und speichern
Beim ersten Start Ihrer App generiert das FCM SDK ein Registrierungs token für die Client-App-Instanz. Dieses Token muss in gezielten Sendeanfragen von der API enthalten sein oder Topic-Abos hinzugefügt werden, um Topics auszurichten.
Wir empfehlen dringend, dass Ihre App dieses Token beim ersten Start abruft und zusammen mit einem Zeitstempel auf Ihrem App-Server speichert. Dieser Zeitstempel muss von Ihrem Code und Ihren Servern implementiert werden, da er nicht von FCM SDKs bereitgestellt wird.
Außerdem ist es wichtig, das Token auf dem Server zu speichern und den Zeitstempel zu aktualisieren, wenn es sich ändert, z. B. wenn:
- Die App auf einem neuen Gerät wiederhergestellt wird
- Der Nutzer die App deinstalliert oder neu installiert
- Der Nutzer App-Daten löscht
- Die App wieder aktiv wird, nachdem FCM das vorhandene Token abgelaufen ist
Beispiel: Tokens und Zeitstempel in Cloud Firestore speichern
Sie können beispielsweise Cloud Firestore verwenden, um Tokens in einer Sammlung
namens fcmTokens zu speichern. Jede Dokument-ID in der Sammlung entspricht einer Nutzer-ID und das Dokument speichert das aktuelle Registrierungstoken und den Zeitstempel der letzten Aktualisierung. Verwenden Sie die Funktion set, wie in diesem Kotlin-Beispiel gezeigt:
/**
* 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)
}
Jedes Mal, wenn ein Token abgerufen wird, wird es durch Aufrufen von
sendTokenToServer in Cloud Firestore gespeichert:
/**
* 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()
}
}
Tokens auf dem neuesten Stand halten und veraltete Tokens entfernen
Es ist nicht immer einfach zu bestimmen, ob ein Token aktuell oder veraltet ist. Um alle Fälle abzudecken, sollten Sie einen Schwellenwert festlegen, ab dem Sie Tokens als veraltet betrachten. Standardmäßig betrachtet FCM ein Token als veraltet, wenn die zugehörige App Instanz seit einem Monat keine Verbindung hergestellt hat. Jedes Token, das älter als einen Monat ist, gehört wahrscheinlich zu einem inaktiven Gerät. Andernfalls wäre das Token auf einem aktiven Gerät aktualisiert worden.
Je nach Anwendungsfall kann ein Monat zu kurz oder zu lang sein. Sie müssen also selbst die Kriterien festlegen, die für Sie am besten geeignet sind.
Ungültige Tokenantworten vom FCM Back-End erkennen
Achten Sie darauf, ungültige Tokenantworten von FCM zu erkennen und zu reagieren, indem Sie alle Registrierungstokens aus Ihrem System löschen, die bekanntermaßen ungültig sind oder abgelaufen sind. Bei der HTTP v1 API können diese Fehlermeldungen darauf hinweisen, dass Ihre Sendeanfrage auf ungültige oder abgelaufene Tokens ausgerichtet war:
UNREGISTERED(HTTP 404)INVALID_ARGUMENT(HTTP 400)
Wenn Sie sicher sind, dass die Nachrichtennutzlast gültig ist, und Sie eine dieser Antworten für ein bestimmtes Token erhalten, können Sie den Eintrag für dieses Token löschen, da es nie wieder gültig sein wird. Wenn Sie beispielsweise ungültige Tokens aus Cloud Firestore löschen möchten, können Sie eine Funktion wie die folgende bereitstellen und ausführen:
// 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 gibt eine ungültige Tokenantwort zurück, wenn ein Token für ein Android-Gerät nach 270 Tagen Inaktivität abgelaufen ist oder wenn ein Client die Registrierung explizit aufgehoben hat. Wenn Sie die Veraltung genauer nach Ihren eigenen Definitionen verfolgen möchten, können Sie veraltete Registrierungstokens proaktiv entfernen.
Tokens regelmäßig aktualisieren
Wir empfehlen, alle Registrierungstokens auf Ihrem Server regelmäßig abzurufen und zu aktualisieren. Dazu müssen Sie Folgendes tun:
- Fügen Sie in Ihrer Client-App App-Logik hinzu, um das aktuelle Token mit dem
entsprechenden API-Aufruf abzurufen (z. B.
token(completion):für Apple-Plattformen odergetToken()für Android) und das aktuelle Token dann zur Speicherung (mit einem Zeitstempel) an Ihren App-Server zu senden. Dies kann ein monatlicher Job sein, der für alle Clients oder Tokens konfiguriert ist. - Fügen Sie Serverlogik hinzu, um den Zeitstempel des Tokens in regelmäßigen Abständen zu aktualisieren, unabhängig davon, ob sich das Token geändert hat oder nicht.
Ein Beispiel für Android-Logik zum Aktualisieren von Tokens mit WorkManager, finden Sie im Firebase-Blog unter Managing Cloud Messaging Tokens.
Unabhängig vom Zeitplan sollten Sie Tokens regelmäßig aktualisieren. Eine Aktualisierungshäufigkeit von einmal pro Monat bietet ein gutes Gleichgewicht zwischen Akkuverbrauch und Erkennung inaktiver Registrierungstokens. Durch diese Aktualisierung wird auch sichergestellt, dass jedes Gerät, das inaktiv wird, seine Registrierung aktualisiert, wenn es wieder aktiv wird. Eine häufigere Aktualisierung als einmal pro Woche bringt keine Vorteile.
Veraltete Registrierungstokens entfernen
Bevor Sie Nachrichten an ein Gerät senden, prüfen Sie, ob der Zeitstempel des Registrierungstokens des Geräts innerhalb des Zeitraums für veraltete Tokens liegt. Sie können beispielsweise Cloud Functions for Firebase implementieren, um täglich zu prüfen, ob der
Zeitstempel innerhalb eines definierten Zeitraums für veraltete Tokens liegt, z. B. const
EXPIRATION_TIME = 1000 * 60 * 60 * 24 * 30; und dann veraltete Tokens entfernen:
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(); });
});
Veraltete Tokens von Topics abmelden
Wenn Sie Topics verwenden, sollten Sie veraltete Tokens auch von den Topics abmelden, für die sie abonniert sind. Dazu sind zwei Schritte erforderlich:
- Ihre App sollte sich einmal pro Monat und immer dann, wenn sich das Registrierungstoken ändert, neu für Topics anmelden. Dies ist eine selbstheilende Lösung, bei der die Abos automatisch wieder angezeigt werden, wenn eine App wieder aktiv wird.
- Wenn eine App-Instanz einen Monat lang inaktiv ist (oder innerhalb Ihres eigenen Zeitraums für veraltete Tokens), sollten Sie sie von Topics abmelden. Verwenden Sie dazu das Firebase Admin SDK um die Zuordnung von Token zu Topic aus dem FCM Backend zu löschen.
Der Vorteil dieser beiden Schritte besteht darin, dass Ihre Fanouts schneller erfolgen, da es weniger veraltete Tokens gibt, an die Fanouts gesendet werden müssen. Außerdem werden Ihre veralteten App-Instanzen automatisch neu abonniert, sobald sie wieder aktiv sind.
Zustellungserfolg messen
Um ein möglichst genaues Bild der Nachrichtenzustellung zu erhalten, sollten Sie Nachrichten nur an aktiv verwendete App-Instanzen senden. Dies ist besonders wichtig, wenn Sie regelmäßig Nachrichten an Topics mit einer großen Anzahl von Abonnenten senden. Wenn ein Teil dieser Abonnenten inaktiv ist, kann sich dies im Laufe der Zeit erheblich auf Ihre Zustellungsstatistiken auswirken.
Bevor Sie Nachrichten an ein Token senden, sollten Sie Folgendes berücksichtigen:
- Deuten Google Analytics-Daten, in BigQuery erfasste Daten oder andere Tracking-Signale darauf hin, dass das Token aktiv ist?
- Sind frühere Zustellungsversuche über einen bestimmten Zeitraum hinweg immer wieder fehlgeschlagen?
- Wurde das Registrierungstoken in den letzten Monaten auf Ihren Servern aktualisiert?
- Meldet die FCM Data API
für Android-Geräte einen hohen Prozentsatz an Fehlern bei der Nachrichtenzustellung aufgrund von
droppedDeviceInactive?
Weitere Informationen zur Zustellung finden Sie unter Informationen zur Nachrichtenzustellung.