Jeśli do tworzenia żądań wysyłania używasz interfejsów API FCM, możesz zauważyć, że z czasem marnujesz zasoby, wysyłając wiadomości do nieaktywnych urządzeń z nieaktualnymi tokenami rejestracji. Może to mieć wpływ na dane dotyczące dostarczania wiadomości raportowane w konsoli Firebase lub dane eksportowane do BigQuery, które będą wyglądać jak znaczny (ale nieprawidłowy) spadek współczynników dostarczania. W tym przewodniku znajdziesz informacje o tym, co możesz zrobić, aby zapewnić skuteczne kierowanie wiadomości i prawidłowe raportowanie ich dostarczania.
Nieaktualne i wygasłe tokeny rejestracji
Nieaktualne tokeny rejestracji to tokeny powiązane z nieaktywnymi urządzeniami, które od ponad miesiąca nie są połączone z FCM. Z czasem prawdopodobieństwo, że urządzenie ponownie połączy się z FCM, maleje. Wiadomości wysyłane i rozpowszechniane w ramach tych tokenów są mało prawdopodobne.
Token może stać się nieaktualny z kilku powodów. Na przykład urządzenie, z którym jest powiązany token, może zostać zgubione, zniszczone lub umieszczone w pamięci i zapomniane.
Gdy nieaktualne tokeny osiągną 270 dni nieaktywności, FCM uzna je za nieaktualne tokeny. Gdy token wygaśnie, FCM oznaczy go jako nieprawidłowy i odrzuci wysyłane do niego wiadomości. Jednak w rzadkich przypadkach, gdy urządzenie ponownie nawiąże połączenie i otworzy aplikację, FCM wygeneruje nowy token.
Podstawowe sprawdzone metody
W każdej aplikacji, która używa interfejsów API FCM do automatycznego tworzenia żądań wysyłanych, należy przestrzegać kilku podstawowych metod. Najważniejsze sprawdzone metody to:
- Pobieraj tokeny rejestracji z FCM i przechowuj je na swoim serwerze. Ważną rolą serwera jest śledzenie tokenów każdego klienta i aktualizowanie listy aktywnych tokenów. Zdecydowanie zalecamy implementację sygnatury czasowej tokena w kodzie i na serwerach oraz aktualizowanie tej sygnatury w regularnych odstępach czasu.
- Dbaj o aktualność tokenów i usuwaj nieaktualne tokeny. Oprócz usuwania tokenów, które FCM już nie uznaje za prawidłowe, możesz też obserwować inne sygnały wskazujące na to, że tokeny stały się nieaktualne, i aktywnie je usuwać. W tym przewodniku omawiamy niektóre z dostępnych opcji.
Pobieranie i przechowywanie tokenów rejestracji
Przy pierwszym uruchomieniu aplikacji pakiet SDK FCM generuje token rejestracji dla instancji aplikacji klienckiej. Jest to token, który musisz umieścić w kierowanych żądaniach wysyłania z interfejsu API lub dodać go do subskrypcji tematów, aby kierować reklamy na tematy.
Zdecydowanie zalecamy, aby aplikacja pobierała ten token podczas uruchamiania i zapisywała go na serwerze aplikacji wraz z sygnaturą czasową. Ten sygnaturę czasową musisz zaimplementować w kodzie i na serwerach, ponieważ nie jest ona udostępniana przez pakiety SDK FCM.
Ważne jest też, aby zapisać token na serwerze i zaktualizować sygnaturę czasową, gdy ulegnie ona zmianie, np. gdy:
- Aplikacja jest przywracana na nowym urządzeniu
- Użytkownik odinstaluje lub ponownie zainstaluje aplikację.
- Użytkownik czyści dane aplikacji
- Aplikacja ponownie stanie się aktywna po wygaśnięciu jej tokena FCM.
Przykład: przechowywanie tokenów i danych o czasie w pliku Cloud Firestore
Możesz na przykład użyć funkcji Cloud Firestore do przechowywania tokenów w kolekcji o nazwie fcmTokens
. Każdy identyfikator dokumentu w kolekcji odpowiada identyfikatorowi użytkownika, a dokument zawiera aktualny token rejestracji i jego ostatnią zaktualizowaną sygnaturę czasową. Użyj funkcji set
w ten sposób:
/**
* 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)
}
Pobierany token jest przechowywany w Cloud Firestore przez wywołanie funkcji 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()
}
}
Utrzymywanie tokenów w stanie aktualności i usuwanie nieaktualnych tokenów
Ustalenie, czy token jest świeży czy nie, nie zawsze jest proste. Aby uwzględnić wszystkie przypadki, należy określić próg, po przekroczeniu którego tokeny są uważane za stałe. Domyślnie FCM uznaje token za nieaktualny, jeśli instancja aplikacji nie była połączona przez miesiąc. Token starszy niż miesiąc prawdopodobnie pochodzi z nieaktywnego urządzenia. Aktywne urządzenie odświeża swój token.
W zależności od przypadku użycia miesiąc może być za krótki lub za długi, więc to od Ciebie zależy, jakie kryteria będą dla Ciebie odpowiednie.
Wykrywanie nieprawidłowych odpowiedzi z tokenem z backendu FCM
Pamiętaj, aby wykrywać nieprawidłowe odpowiedzi z usług FCM i usuwać z systemu wszystkie tokeny rejestracji, które są nieprawidłowe lub których ważność wygasła. W przypadku interfejsu HTTP w wersji 1 te komunikaty o błędach mogą wskazywać, że żądanie wysyłania było kierowane do nieprawidłowych lub nieważnych tokenów:
UNREGISTERED
(HTTP 404)INVALID_ARGUMENT
(HTTP 400)
Jeśli masz pewność, że ładunek wiadomości jest prawidłowy i otrzymasz jedną z tych odpowiedzi dla docelowego tokena, możesz bezpiecznie usunąć rekord tego tokena, ponieważ nigdy nie będzie on prawidłowy. Aby na przykład usunąć nieprawidłowe tokeny z Cloud Firestore, możesz wdrożyć i uruchomić funkcję o takim kształcie:
// 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 zwraca nieprawidłową odpowiedź tokena tylko wtedy, gdy token wygaśnie po 270 dniach lub jeśli klient wyraźnie się wyrejestrował. Jeśli chcesz dokładniej śledzić brak aktualizacji zgodnie z własnymi definicjami, możesz proaktywnie usuwać nieaktualne tokeny rejestracji.
Regularnie aktualizuj tokeny
Zalecamy okresowe pobieranie i aktualizowanie wszystkich tokenów rejestracji na serwerze. Wymagania:
- Dodaj logikę aplikacji do aplikacji klienckiej, aby pobrać bieżący token za pomocą odpowiedniego wywołania interfejsu API (np.
token(completion):
w przypadku platform Apple lubgetToken()
w przypadku Androida), a następnie wyślij bieżący token do serwera aplikacji w celu zapisania go (z sygnaturą czasową). Może to być zadanie uruchamiane co miesiąc, które obejmuje wszystkich klientów lub tokeny. - Dodaj logikę serwera, aby co jakiś czas aktualizować sygnaturę czasową tokena, niezależnie od tego, czy token się zmienił.
Przykład logiki na Androida służącej do aktualizowania tokenów za pomocą WorkManagera znajdziesz w blogu Firebase Zarządzanie tokenami Komunikacji w chmurze.
Niezależnie od tego, jaki schemat czasowy stosujesz, pamiętaj o okresowej aktualizacji tokenów. Częstotliwość aktualizacji raz w miesiącu zapewnia odpowiednią równowagę między wpływem na baterię a wykrywaniem nieaktywnych tokenów rejestracji. Dzięki temu masz też pewność, że każde urządzenie, które stanie się nieaktywne, będzie mieć odświeżoną rejestrację, gdy znów stanie się aktywne. Odświeżanie częściej niż raz w tygodniu nie przynosi żadnych korzyści.
Usuwanie nieaktualnych tokenów rejestracji
Przed wysłaniem wiadomości na urządzenie upewnij się, że sygnatura czasowa tokena rejestracji urządzenia mieści się w okresie braku aktualizacji. Możesz na przykład zaimplementować Cloud Functions for Firebase, aby codziennie sprawdzać, czy sygnatura czasowa mieści się w określonym okresie nieaktualności, np. const
EXPIRATION_TIME = 1000 * 60 * 60 * 24 * 30;
, a następnie usuwać nieaktualne tokeny:
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(); });
});
anulowanie nieaktualnych tokenów z tematów.
Jeśli używasz tematów, możesz też zarejestrować nieaktualne tokeny z tematów, do których są one subskrybowane. Ten proces składa się z 2 etapów:
- Aplikacja powinna ponownie subskrybować tematy raz w miesiącu i po każdej zmianie tokena rejestracji. Jest to rozwiązanie samonaprawiające się, w którym subskrypcje pojawiają się automatycznie, gdy aplikacja znów stanie się aktywna.
- Jeśli instancja aplikacji jest nieaktywna przez miesiąc (lub przez okres, który określasz samodzielnie), powinnaś anulować subskrypcję tematów za pomocą pakietu Firebase Admin SDK, aby usunąć mapowanie tokenów na tematy z poziomu backendu FCM.
Dzięki tym 2 krokom rozgałęzienia będą się pojawiać szybciej, ponieważ jest mniej nieaktualnych tokenów, do których można się rozgałęzić, a nieaktualne instancje aplikacji automatycznie ponownie się subskrybują, gdy znów będą aktywne.
Pomiar skuteczności przesyłania
Aby uzyskać jak najbardziej dokładny obraz dostarczania wiadomości, najlepiej wysyłać wiadomości tylko do aktywnie używanych instancji aplikacji. Jest to szczególnie ważne, jeśli regularnie wysyłasz wiadomości na tematy, które mają dużą liczbę subskrybentów. Jeśli część z nich jest nieaktywna, wpływ na statystyki dotyczące dostarczania może z czasem wzrosnąć.
Zanim utworzysz kierowanie wiadomości na token, weź pod uwagę te kwestie:
- Czy Google Analytics, dane przechwycone w BigQuery lub inne sygnały śledzenia wskazują, że token jest aktywny?
- Czy wcześniejsze próby dostarczenia wiadomości w danym okresie nie udawały się regularnie?
- Czy token rejestracji został zaktualizowany na Twoich serwerach w ciągu ostatniego miesiąca?
- Czy w przypadku urządzeń z Androidem interfejs API danych FCM zgłasza wysoki odsetek niepowodzeń przy dostarczaniu wiadomości z powodu
droppedDeviceInactive
?
Więcej informacji o dostarczaniu wiadomości znajdziesz w artykule Dostarczanie wiadomości.