Wenn Sie FCM-APIs verwenden, um Sendeanfragen programmatisch zu erstellen, stellen Sie möglicherweise fest, dass Sie im Laufe der Zeit Ressourcen verschwenden, indem Sie Nachrichten an inaktive Geräte mit veralteten Registrierungstokens senden. Dies kann sich auf die in der Firebase-Konsole gemeldeten Daten zur Nachrichtenzustellung oder auf nach BigQuery exportierte Daten auswirken und 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 Ausrichtung von Nachrichten und eine gültige Zustellungsberichterstellung zu gewährleisten.
Veraltete und abgelaufene Registrierungstokens
Abgelaufene Registrierungstokens sind Tokens, die mit inaktiven Geräten verknüpft sind, die seit über einem Monat keine Verbindung zu FCM hergestellt haben. Mit der Zeit wird es immer unwahrscheinlicher, dass sich das Gerät jemals wieder mit FCM verbindet. Nachrichtensendungen und Topic-Fanouts für diese veralteten Tokens werden wahrscheinlich nie zugestellt.
Es gibt mehrere Gründe, warum ein Token abgelaufen sein kann. Das Gerät, mit dem das Token verknüpft ist, kann beispielsweise verloren gehen, zerstört werden oder eingelagert und vergessen werden.
Wenn inaktive Tokens 270 Tage lang nicht verwendet wurden, werden sie von FCM als abgelaufene Tokens betrachtet. Sobald ein Token abläuft, kennzeichnet FCM es als ungültig und lehnt Sendungen an das Token ab. FCM stellt jedoch ein neues Token für die App-Instanz aus, wenn das Gerät wieder verbunden und die App geöffnet wird.
Grundlegende Best Practices
Es gibt einige grundlegende Vorgehensweisen, die Sie in jeder App befolgen sollten, in der FCM-APIs verwendet werden, um Anfragen programmatisch zu erstellen. Die wichtigsten Best Practices sind:
- Registrierungstokens von FCM abrufen und auf Ihrem Server speichern: Eine wichtige Aufgabe des Servers ist es, das Token jedes Clients zu verfolgen und eine aktualisierte Liste der aktiven Tokens zu führen. Wir empfehlen dringend, einen Token-Zeitstempel in Ihren Code und Ihre Server zu implementieren und diesen Zeitstempel in regelmäßigen Abständen zu aktualisieren.
- Aktualität von Tokens aufrechterhalten und alte Tokens entfernen: Zusätzlich zum Entfernen von Tokens, die FCM nicht mehr als gültig betrachtet, sollten Sie auch andere Anzeichen dafür beobachten, dass Tokens veraltet sind, und sie proaktiv entfernen. In dieser Anleitung werden einige Optionen beschrieben, mit denen Sie dies erreichen können.
Registrierungstokens abrufen und speichern
Beim ersten Start Ihrer App generiert das FCM SDK ein Registrierungstoken für die Client-App-Instanz. Dieses Token muss in gezielten Sendeanfragen über die API enthalten sein oder Thema-Abos hinzugefügt werden, um Themen zu targetieren.
Wir empfehlen dringend, dass Ihre App dieses Token beim ersten Start abruft und es 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 er sich ändert, z. B. wenn:
- Die App wird auf einem neuen Gerät wiederhergestellt
- Der Nutzer deinstalliert oder installiert die App neu.
- Der Nutzer löscht App-Daten.
- Die App wird wieder aktiv, nachdem FCM das vorhandene Token ablaufen lassen hat.
Beispiel: Speichern von Tokens und Zeitstempeln in Cloud Firestore
Sie könnten beispielsweise Cloud Firestore verwenden, um Tokens in einer Sammlung namens fcmTokens
zu speichern. Jede Dokument-ID in der Sammlung entspricht einer Nutzer-ID. Im Dokument werden das aktuelle Registrierungstoken und der Zeitstempel der letzten Aktualisierung gespeichert. 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 in Cloud Firestore gespeichert, indem sendTokenToServer
aufgerufen wird:
/**
* 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 aktuell halten und veraltete Tokens entfernen
Es ist nicht immer einfach, festzustellen, ob ein Token neu oder abgelaufen 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 mehr hergestellt hat. Alle Token, die älter als ein Monat sind, gehören wahrscheinlich zu einem inaktiven Gerät. Ein aktives Gerät hätte sein Token aktualisiert.
Je nach Anwendungsfall kann ein Monat zu kurz oder zu lang sein. Sie müssen also selbst entscheiden, welche Kriterien für Sie am besten geeignet sind.
Ungültige Tokenantworten vom FCM-Backend erkennen
Achten Sie darauf, ungültige Tokenantworten von FCM zu erkennen und darauf zu reagieren, indem Sie alle Registrierungstokens, die als ungültig bekannt sind oder abgelaufen sind, aus Ihrem System löschen. 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 Zieltoken erhalten, können Sie den Datensatz 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 (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 nur dann eine Antwort mit einem ungültigen Token zurück, wenn ein Token nach 270 Tagen abgelaufen ist oder wenn ein Client die Registrierung explizit aufgehoben hat. Wenn Sie die Aktualität genauer nach Ihren eigenen Definitionen erfassen müssen, können Sie abgelaufene Registrierungstokens proaktiv entfernen.
Tokens regelmäßig aktualisieren
Wir empfehlen, alle Registrierungstokens auf Ihrem Server regelmäßig abzurufen und zu aktualisieren. Dazu ist Folgendes erforderlich:
- Fügen Sie 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). Senden Sie das aktuelle Token dann zur Speicherung (mit einem Zeitstempel) an Ihren App-Server. Das kann ein monatlicher Job sein, der für alle Kunden 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 die Android-Logik zum Aktualisieren von Tokens mit WorkManager finden Sie im Firebase-Blog unter Managing Cloud Messaging Tokens.
Unabhängig davon, welchem Zeitmuster Sie folgen, sollten Sie Tokens regelmäßig aktualisieren. Eine Aktualisierungshäufigkeit von einmal pro Monat bietet ein gutes Gleichgewicht zwischen dem Akkuverbrauch und dem Erkennen inaktiver Registrierungstokens. Durch diese Aktualisierung wird auch dafür gesorgt, dass die Registrierung aller Geräte, die inaktiv werden, aktualisiert wird, wenn sie wieder aktiv werden. Eine Aktualisierung, die häufiger als wöchentlich erfolgt, bietet keine Vorteile.
Veraltete Registrierungstokens entfernen
Bevor Sie Nachrichten an ein Gerät senden, müssen Sie darauf achten, dass der Zeitstempel des Registrierungstokens des Geräts innerhalb des Zeitraums für die Aktualität 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 Daten wie const
EXPIRATION_TIME = 1000 * 60 * 60 * 24 * 30;
liegt, 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(); });
});
Alte Tokens von Themen abmelden
Wenn Sie Themen verwenden, sollten Sie möglicherweise auch alte Tokens von den Themen abmelden, für die sie registriert sind. Dazu sind zwei Schritte erforderlich:
- Ihre App sollte sich einmal pro Monat und immer dann neu für Themen registrieren, wenn sich das Registrierungstoken ändert. So entsteht eine Lösung, die sich selbst repariert: Die Abos werden automatisch wieder angezeigt, wenn eine App wieder aktiv wird.
- Wenn eine App-Instanz einen Monat lang (oder entsprechend Ihrem eigenen Inaktivitätszeitraum) inaktiv ist, sollten Sie sie mit dem Firebase Admin SDK von Themen abmelden, um die Zuordnung von Token zu Themen aus dem FCM-Backend zu löschen.
Der Vorteil dieser beiden Schritte besteht darin, dass Ihre Fanouts schneller erfolgen, da es weniger alte Tokens gibt, an die sie gesendet werden müssen. Außerdem werden Ihre alten App-Instanzen automatisch neu abonniert, sobald sie wieder aktiv sind.
Liefererfolg messen
Um ein möglichst genaues Bild der Nachrichtenzustellung zu erhalten, sollten Sie Nachrichten nur an aktiv verwendete App-Instanzen senden. Das ist besonders wichtig, wenn Sie regelmäßig Nachrichten an Themen mit einer großen Anzahl von Abonnenten senden. Wenn ein Teil dieser Abonnenten tatsächlich inaktiv ist, kann sich das im Laufe der Zeit erheblich auf Ihre Zustellstatistiken auswirken.
Bevor Sie Nachrichten auf ein Token ausrichten, sollten Sie Folgendes beachten:
- Gibt es in Google Analytics, in BigQuery erfassten Daten oder anderen Tracking-Signalen Hinweise darauf, dass das Token aktiv ist?
- Sind frühere Zustellversuche über einen längeren Zeitraum hinweg immer wieder fehlgeschlagen?
- Wurde das Registrierungstoken in den letzten Monaten auf Ihren Servern aktualisiert?
- Wird in der FCM Data API für Android-Geräte ein hoher Prozentsatz von Fehlern bei der Nachrichtenzustellung aufgrund von
droppedDeviceInactive
gemeldet?
Weitere Informationen zur Zustellung finden Sie unter Informationen zur Nachrichtenzustellung.