Wenn Sie FCM APIs verwenden, um Sendeanfragen programmatisch zu erstellen, kann es sein, dass Sie im Laufe der Zeit Ressourcen verschwenden, weil Sie Nachrichten an inaktive Geräte mit veralteten Registrierungen senden. Diese Situation kann sich auf die in der Firebase-Konsole gemeldeten Daten zur Nachrichtenzustellung oder auf die nach BigQuery exportierten Daten auswirken und als drastischer (aber nicht tatsächlich gültiger) Rückgang der Zustellungsraten angezeigt werden. In diesem Leitfaden werden einige Maßnahmen erläutert, mit denen Sie für eine effiziente Ausrichtung von Mitteilungen und eine gültige Berichterstellung zur Auslieferung sorgen können.
Veraltete und abgelaufene Registrierungen
Veraltete Registrierungen sind mit inaktiven Geräten verknüpft, die seit mehr als einem Monat keine Verbindung zu FCM hergestellt haben. Mit der Zeit wird es immer unwahrscheinlicher, dass das Gerät jemals wieder eine Verbindung zu FCM herstellt. Es ist unwahrscheinlich, dass Nachrichten und Themen-Fanouts für diese veralteten Registrierungen jemals zugestellt werden.
Es gibt mehrere Gründe, warum eine Registrierung veraltet sein kann. Beispielsweise kann das Gerät, mit dem die Registrierung verknüpft ist, verloren gehen, zerstört oder eingelagert und vergessen werden.
Wenn eine Registrierung unter Android 270 Tage lang inaktiv war, wird sie von FCM als abgelaufen betrachtet und gelöscht. Wenn eine Registrierung abgelaufen ist, wird sie von FCM als ungültig markiert und Nachrichten an sie werden abgelehnt. Firebase-Installations-IDs (FIDs) werden vom Firebase-Installationsdienst (FIS) verwaltet, nicht von FCM. In dem seltenen Fall, dass ein Gerät wieder eine Verbindung herstellt und die App geöffnet wird, nachdem die Registrierung gelöscht wurde, registriert sich die Client-App noch einmal bei FCM. Dazu wird die von FIS abgerufene FID verwendet. Die FID kann sich ändern. Weitere Informationen dazu, wann FIDs neu ausgestellt werden, finden Sie unter Firebase-Installationen verwalten.
Auf anderen Plattformen wie iOS basiert FCM auf dem zugrunde liegenden Push-Dienst (z.B. APNs), der nicht dieselbe 270-tägige Inaktivitätsfrist hat. Wir empfehlen, die Registrierungen proaktiv auf dem neuesten Stand zu halten und veraltete Registrierungen zu entfernen.
Grundlegende Best Practices
Es gibt einige grundlegende Praktiken, die Sie in jeder App befolgen sollten, die FCM APIs verwendet, um Sendeanfragen programmatisch zu erstellen. Die wichtigsten Best Practices sind:
- Rufen Sie Firebase-Installations-IDs (FIDs) von FCM ab und speichern Sie sie auf Ihrem App-Server. Eine wichtige Aufgabe des Servers besteht darin, die registrierte FID jedes Clients zu verfolgen und eine aktuelle Liste der aktiven FIDs zu führen. Wir empfehlen dringend, einen Registrierungszeitstempel in Ihrer Datenbank zu implementieren und ihn bei jedem Upload einer Registrierung zu aktualisieren.
- Registrierungen aktuell halten und veraltete Registrierungen entfernen Zusätzlich zum Entfernen von Registrierungen, die FCM nicht mehr als gültig ansieht, sollten Sie auch andere Anzeichen dafür im Auge behalten, dass Registrierungen veraltet sind, und diese proaktiv entfernen. In diesem Leitfaden werden einige Optionen dafür erläutert.
Firebase-Installations-IDs abrufen und speichern
Beim ersten Start Ihrer App registriert das FCM SDK die App-Instanz bei FCM und gibt eine Firebase-Installations-ID (FID) zurück. Diese Kennung müssen Sie in gezielte Sendeanfragen der API einfügen oder für Themenabos verwenden.
Wir empfehlen dringend, die FID zusammen mit einem Zeitstempel auf Ihrem App-Server zu speichern, wenn sie hochgeladen wird. Durch die Aktualisierung des Zeitstempels bei jeder Uploadanfrage weiß Ihr Server, wann die App-Instanz zuletzt geöffnet und erfolgreich mit dem FCM-Backend synchronisiert wurde.
Je nachdem, ob die automatische Initialisierung aktiviert oder deaktiviert ist (einschließlich nicht unterstützt), sollten Sie die Registrierung und Aktualisierungen so handhaben:
- (Empfohlen) Wenn die automatische Initialisierung aktiviert ist:Das SDK hält die Registrierung automatisch auf dem neuesten Stand und überwacht Änderungen. Der Callback
onRegistered()wird regelmäßig bei routinemäßigen Synchronisierungen während des App-Starts sowie bei Änderungen der FID aufgerufen. Implementieren Sie einfach diesen Callback, um die FID auf Ihren Server hochzuladen und den aktuellen Zeitstempel zu speichern. - Wenn die automatische Initialisierung deaktiviert ist:Der Callback
onRegistered()wird beim Start nicht automatisch aufgerufen. Wenn Sie Registrierungen im Blick behalten und aktualisieren möchten, rufen Sie beim Start der Appregister()auf, z. B. unter Android in deronCreate()der Hauptaktivität. Ein erfolgreicher Aufruf löst den FCM-Registrierungsprozess mit der FID aus und liefert sie an IhrenonRegistered()-Callback. So kann Ihre App die FID hochladen und den Zeitstempel auf Ihrem Server aktualisieren.
Beispiel: FIDs und Zeitstempel in Cloud Firestore speichern
Sie können beispielsweise Cloud Firestore verwenden, um FIDs in einer Sammlung namens fcmRegistrations zu speichern. Jede Dokument-ID in der Sammlung entspricht einer Nutzer-ID. Das Dokument speichert die aktuelle FID und den Zeitstempel der letzten Aktualisierung. Verwenden Sie die Funktion set, wie in diesem Kotlin-Beispiel gezeigt:
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)
}
Wenn eine Firebase-Installations-ID erfolgreich registriert oder aktualisiert wurde, wird der Callback onRegistered() aufgerufen. Du solltest diesen Callback implementieren, um die FID hochzuladen und den Zeitstempel zu aktualisieren:
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)
}
Wenn die automatische Initialisierung deaktiviert ist, rufen Sie beim Start der App register() auf (z.B. in onCreate()), um den Registrierungsablauf und die FID-Bereitstellung über onRegistered() auszulösen:
// 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)
}
}
Aktualität der Registrierungen aufrechterhalten und veraltete Registrierungen entfernen
Es ist nicht immer einfach, festzustellen, ob eine Registrierung aktuell oder veraltet ist. Um alle Fälle abzudecken, sollten Sie einen Schwellenwert festlegen, ab dem Registrierungen als veraltet gelten. Standardmäßig betrachtet FCM eine Registrierung als veraltet, wenn die zugehörige App-Instanz seit einem Monat keine Verbindung hergestellt hat. Jede Registrierung, die älter als ein Monat ist, ist wahrscheinlich ein inaktives Gerät. Ein aktives Gerät hätte seine Registrierung sonst 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 Antworten vom FCM-Backend erkennen
Achte darauf, ungültige Antworten von FCM zu erkennen und darauf zu reagieren, indem du alle Registrierungen, die bekanntermaßen ungültig oder abgelaufen sind, aus deinem System löschst. Bei der HTTP v1 API können diese Fehlermeldungen darauf hinweisen, dass Ihre Sendeanfrage auf ungültige oder abgelaufene Registrierungen abzielte:
UNREGISTERED(HTTP 404)INVALID_ARGUMENT(HTTP 400)
Wenn du sicher bist, dass die Nachrichtennutzlast gültig ist, und du eine dieser Antworten für eine Zielregistrierung erhältst, kannst du den Eintrag für diese Registrierung löschen, da er nie wieder gültig sein wird. Wenn Sie beispielsweise ungültige Registrierungen aus Cloud Firestore löschen möchten, können Sie eine Funktion wie die folgende bereitstellen und ausführen:
// 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 gibt eine ungültige Antwort zurück, wenn die Registrierung für ein Android-Gerät nach 270 Tagen Inaktivität abgelaufen ist oder wenn sich ein Client explizit abgemeldet hat. Wenn Sie die Veraltung genauer nach Ihren eigenen Definitionen verfolgen möchten, können Sie veraltete Registrierungen proaktiv entfernen.
Registrierungen regelmäßig aktualisieren
Unabhängig davon, ob Ihre Registrierungen auf FIDs oder Legacy-Registrierungstokens basieren, sollte Ihr Server bei jeder Uploadanfrage den Registrierungszeitstempel in Ihrer Datenbank aktualisieren. Dieser Zeitstempel dient als Signal für die App-Installation, sodass der Client die App erfolgreich öffnen und mit dem FCM-Backend synchronisieren kann. Implementieren Sie je nach den von Ihnen verwendeten APIs die entsprechende Strategie:
Die Firebase Installation ID APIs (empfohlen)
Für Client-Apps, die die FID APIs verwenden, müssen Sie keine regelmäßigen Hintergrundjobs in Ihrer Client-App planen, um Registrierungen abzurufen oder zu aktualisieren. Das SDK kümmert sich bei der automatischen Initialisierung automatisch um Aktualisierungen und liefert bei routinemäßigen Synchronisierungen während des App-Starts regelmäßig die richtige aktuelle FID an den onRegistered()-Callback.
Damit Ihr Server auf dem neuesten Stand bleibt, sollten Sie die Strategien zum Hochladen beim Start implementieren, die unter Firebase-Installations-IDs abrufen und speichern beschrieben sind:
- Automatische Initialisierung aktiviert:Das SDK sorgt automatisch dafür, dass die neueste FID bei routinemäßigen Synchronisierungen während des App-Starts an Ihren Server gesendet wird.
- Automatische Initialisierung deaktiviert oder nicht unterstützt:Rufen Sie beim Start der App
register()auf (z. B. unter Android in deronCreate()der Hauptaktivität), um die Registrierungssequenz zu erzwingen und die FID-Bereitstellung für IhrenonRegistered()-Callback auszulösen.
Diese Strategien sorgen dafür, dass Ihr Server immer die neueste aktive FID hat und sich automatisch von fehlgeschlagenen Uploads erholen kann. Dadurch wird die Anwendung sehr widerstandsfähig.
Die verworfenen APIs für Registrierungstokens
Wenn Sie alte Registrierungstokens verwenden, verwaltet das Client-SDK Aktualisierungen bei routinemäßigen Synchronisierungen nicht automatisch. Daher empfehlen wir, alle Registrierungstokens auf Ihrem Server regelmäßig abzurufen und zu aktualisieren. Dazu ist Folgendes zu tun:
- 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. Dies könnte ein monatlicher Job sein, der so konfiguriert ist, dass er alle Clients oder Tokens abdeckt. - 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 Legacy-Tokens mit WorkManager finden Sie im Firebase-Blog unter Managing Cloud Messaging Tokens.
Unabhängig davon, welches Zeitmuster Sie verwenden, sollten Sie Tokens regelmäßig aktualisieren. Eine Updatehäufigkeit von einmal pro Monat ist ein guter Kompromiss zwischen Akkuleistung 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. Es bringt nichts, die Aktualisierung häufiger als einmal pro Woche durchzuführen.
Veraltete Registrierungen entfernen
Bevor Sie Nachrichten an ein Gerät senden, muss der Zeitstempel der Geräteregistrierung innerhalb des Zeitfensters für die Veraltung liegen. 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 liegt, z. B. const
EXPIRATION_TIME = 1000 * 60 * 60 * 24 * 30;, und dann veraltete Registrierungen entfernen:
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(); });
});
Veraltete Registrierungen von Themen abmelden
Wenn Sie Themen verwenden, sollten Sie auch veraltete Registrierungen von den Themen abbestellen, die sie abonniert haben. Dazu sind zwei Schritte erforderlich:
- Ihre App sollte Themen immer dann neu abonnieren, wenn sich die Firebase-Installations-ID (FID) ändert. Dadurch werden die Abos automatisch wieder angezeigt, wenn eine App wieder aktiv wird.
- Wenn eine App-Instanz einen Monat lang (oder für einen von Ihnen festgelegten Zeitraum) inaktiv ist, sollten Sie sie mit dem Firebase Admin SDK von Themen abmelden, um die Zuordnung der Firebase-Installations-ID zum Thema aus dem FCM-Back-End zu löschen.
Der Vorteil dieser beiden Schritte besteht darin, dass die Fanouts schneller erfolgen, da weniger veraltete Registrierungen vorhanden sind, an die die Fanouts gesendet werden müssen. Außerdem werden Ihre veralteten App-Instanzen automatisch wieder abonniert, sobald sie wieder aktiv sind.
Liefererfolg messen
Um ein möglichst genaues Bild der Nachrichtenzustellung zu erhalten, sollten Sie Nachrichten nur an aktiv genutzte App-Instanzen senden. Dies 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 dies im Laufe der Zeit erhebliche Auswirkungen auf Ihre Zustellungsstatistiken haben.
Bevor Sie Nachrichten auf eine App-Instanz ausrichten, sollten Sie Folgendes beachten:
- Gibt es in Google Analytics, in BigQuery erfassten Daten oder anderen Tracking-Signalen Hinweise darauf, dass die Registrierung aktiv ist?
- Sind frühere Zustellversuche über einen längeren Zeitraum hinweg immer wieder fehlgeschlagen?
- Wurde die Firebase-Installations-ID im letzten Monat 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.