Gönderme isteklerini programatik olarak oluşturmak için FCM API'lerini kullanıyorsanız zaman içinde eski kayıt jetonlarına sahip etkin olmayan cihazlara mesaj göndererek kaynak israf ettiğinizi fark edebilirsiniz. Bu durum, Firebase konsolunda raporlanan mesaj yayını verilerini veya BigQuery'ye aktarılan verileri etkileyebilir. Bu durumda, yayın oranlarında önemli (ancak aslında geçerli olmayan) bir düşüş görülebilir. Bu kılavuzda, etkili ileti hedefleme ve geçerli teslimat raporlaması sağlamak için uygulayabileceğiniz bazı önlemler ele alınmaktadır.
Eski ve süresi dolmuş kayıt jetonları
Eski kayıt jetonları, bir aydan uzun süredir FCM'e bağlanmayan etkin olmayan cihazlarla ilişkili jetonlardır. Zaman geçtikçe cihazın FCM'e tekrar bağlanma olasılığı azalır. Bu eski jetonlar için mesaj gönderme ve konu dağıtımlarının teslim edilme olasılığı yoktur.
Bir jetonun eski olmasının birkaç nedeni vardır. Örneğin, jetonun ilişkili olduğu cihaz kaybolabilir, imha edilebilir veya depoya kaldırılıp unutulabilir.
Eski jetonlar 270 gün boyunca etkin olmadığında FCM bunları geçersiz jetonlar olarak kabul eder. Bir jetonun süresi dolduktan sonra FCM, jetonu geçersiz olarak işaretler ve jetona gönderilen mesajları reddeder. Ancak FCM, cihazın tekrar bağlanıp uygulamanın açılması gibi nadir durumlarda uygulama örneği için yeni bir jeton yayınlar.
Temel en iyi uygulamalar
Programatik olarak istek göndermek için FCM API'lerini kullanan tüm uygulamalarda uygulamanız gereken bazı temel uygulamalar vardır. En iyi uygulamalardan bazıları şunlardır:
- FCM'dan kayıt jetonlarını alıp sunucunuzda saklayın. Sunucunun önemli bir rolü, her istemcinin jetonunu takip etmek ve etkin jetonların güncel bir listesini tutmaktır. Kodunuza ve sunucularınıza jeton zaman damgası uygulamanızı ve bu zaman damgasını düzenli aralıklarla güncellemenizi önemle tavsiye ederiz.
- Jetonların güncelliğini koruyun ve eski jetonları kaldırın. FCM'nin artık geçerli olarak kabul etmediği jetonları kaldırmanın yanı sıra, jetonların eskidiğine dair diğer işaretleri de izlemek ve bunları proaktif olarak kaldırmak isteyebilirsiniz. Bu kılavuzda, bu hedefe ulaşmak için kullanabileceğiniz seçeneklerden bazıları ele alınmaktadır.
Kayıt jetonlarını alma ve saklama
Uygulamanız ilk kez başlatıldığında FCM SDK'sı, istemci uygulama örneği için bir kayıt jetonu oluşturur. Bu, API'den gelen hedeflenmiş gönderme isteklerine eklemeniz veya konuları hedeflemek için konu aboneliklerine eklemeniz gereken jetondur.
Uygulamanızın ilk başlatmada bu jetonu almasını ve bir zaman damgasıyla birlikte uygulama sunucunuza kaydetmesini önemle tavsiye ederiz. Bu zaman damgası, FCM SDK'ları tarafından size sağlanmadığından kodunuz ve sunucularınız tarafından uygulanmalıdır.
Ayrıca, jetonu sunucuya kaydetmeniz ve zaman damgasını her değiştiğinde güncellemeniz önemlidir. Örneğin:
- Uygulama yeni bir cihaza geri yüklendiğinde
- Kullanıcı uygulamayı kaldırır veya yeniden yükler
- Kullanıcı uygulama verilerini temizler
- FCM mevcut jetonunun süresinin dolmasından sonra uygulama tekrar etkin hale gelir
Örnek: store tokens and timestamps in Cloud Firestore
Örneğin, jetonları fcmTokens
adlı bir koleksiyonda depolamak için Cloud Firestore kullanabilirsiniz. Koleksiyondaki her belge kimliği bir kullanıcı kimliğine karşılık gelir ve belge, mevcut kayıt jetonunu ve son güncellenme zaman damgasını depolar. set
işlevini bu Kotlin örneğinde gösterildiği gibi kullanın:
/**
* 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)
}
Her jeton alındığında sendTokenToServer
çağrılarak Cloud Firestore içinde saklanır:
/**
* 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()
}
}
Jetonların güncelliğini koruma ve eski jetonları kaldırma
Bir jetonun yeni mi yoksa eski mi olduğunu belirlemek her zaman kolay değildir. Tüm durumları kapsayacak şekilde, jetonları ne zaman eski olarak değerlendireceğinize dair bir eşik belirlemeniz gerekir. Varsayılan olarak FCM, uygulama örneği bir ay boyunca bağlanmamışsa jetonu eski olarak kabul eder. Bir aydan eski jetonlar muhtemelen etkin olmayan cihazlara aittir. Etkin cihazlar jetonlarını yeniler.
Kullanım alanınıza bağlı olarak bir ay çok kısa veya çok uzun olabilir. Bu nedenle, sizin için uygun olan ölçütleri belirlemek size bağlıdır.
FCM arka ucundan geçersiz jeton yanıtlarını algılama
FCM tarafından gönderilen geçersiz jeton yanıtlarını algıladığınızdan ve geçersiz olduğu veya süresi dolduğu bilinen tüm kayıt jetonlarını sisteminizden silerek yanıt verdiğinizden emin olun. HTTP v1 API'de aşağıdaki hata mesajları, gönderme isteğinizin geçersiz veya süresi dolmuş jetonları hedeflediğini gösterebilir:
UNREGISTERED
(HTTP 404)INVALID_ARGUMENT
(HTTP 400)
Mesaj yayının geçerli olduğundan eminseniz ve hedeflenen jeton için bu yanıtlardan birini alırsanız bu jetonla ilgili kaydınızı silebilirsiniz. Bu jeton bir daha geçerli olmayacak. Örneğin, Cloud Firestore kaynağındaki geçersiz jetonları silmek için aşağıdaki gibi bir işlev dağıtıp çalıştırabilirsiniz:
// 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 yalnızca bir jetonun geçerlilik süresi 270 gün sonra sona ererse veya bir istemci açıkça kaydını iptal ederse geçersiz jeton yanıtı döndürür. Eskiliği kendi tanımlarınıza göre daha doğru bir şekilde izlemeniz gerekiyorsa proaktif olarak eski kayıt jetonlarını kaldırabilirsiniz.
Jetonları düzenli olarak güncelleme
Sunucunuzdaki tüm kayıt jetonlarını düzenli olarak almanızı ve güncellemenizi öneririz. Bunun için:
- İstemci uygulamanıza, uygun API çağrısını (ör. Apple platformları için
token(completion):
veya Android içingetToken()
) kullanarak mevcut jetonu almak ve ardından mevcut jetonu depolanması için uygulama sunucunuza göndermek (zaman damgasıyla) üzere uygulama mantığı ekleyin. Bu, tüm istemcileri veya jetonları kapsayacak şekilde yapılandırılmış aylık bir iş olabilir. - Jetonun değişip değişmediğinden bağımsız olarak jetonun zaman damgasını düzenli aralıklarla güncellemek için sunucu mantığı ekleyin.
WorkManager'ı kullanarak jetonları güncellemeye yönelik Android mantığı örneği için Firebase blogundaki Cloud Messaging Jetonlarını Yönetme başlıklı makaleyi inceleyin.
Hangi zamanlama düzenini izlerseniz izleyin jetonları düzenli olarak güncellediğinizden emin olun. Ayda bir güncelleme sıklığı, pil üzerindeki etki ile etkin olmayan kayıt jetonlarının algılanması arasında iyi bir denge sağlar. Bu yenilemeyi yaparak, etkinliği durdurulan cihazların tekrar etkinleştirildiğinde kayıtlarının yenilenmesini de sağlarsınız. Yenilemeyi haftalıktan daha sık yapmanın bir faydası yoktur.
Eski kayıt jetonlarını kaldırma
Bir cihaza mesaj göndermeden önce, cihazın kayıt jetonunun zaman damgasının eskilik aralığı içinde olduğundan emin olun. Örneğin, zaman damgasının const
EXPIRATION_TIME = 1000 * 60 * 60 * 24 * 30;
gibi tanımlanmış bir eskilik aralığı içinde olduğundan emin olmak için günlük kontrol çalıştırmak üzere Cloud Functions for Firebase'ü uygulayabilir ve ardından eski jetonları kaldırabilirsiniz:
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(); });
});
Eski jetonları konulardan çıkarma
Konu kullanıyorsanız abone oldukları konulardaki eski jetonların kaydını da silebilirsiniz. Bu işlem iki adımdan oluşur:
- Uygulamanız, konulara ayda bir kez ve kayıt jetonu değiştiğinde yeniden abone olmalıdır. Bu, bir uygulama tekrar etkin olduğunda aboneliklerin otomatik olarak yeniden göründüğü kendi kendini iyileştiren bir çözüm oluşturur.
- Bir uygulama örneği bir ay boyunca (veya kendi eskilik aralığınız) etkin değilse FCM arka ucundan jetonla konu eşlemesini silmek için Firebase Admin SDK'sını kullanarak uygulamanın konu aboneliğini iptal etmeniz gerekir.
Bu iki adımın avantajı, dağıtılacak eski jeton sayısı daha az olduğu için dağıtımlarınızın daha hızlı gerçekleşmesi ve eski uygulama örnekleriniz tekrar etkinleştirildiğinde otomatik olarak yeniden abone olmasıdır.
Yayınlama başarısını ölçme
Mesaj yayını hakkında en doğru bilgileri almak için mesajları yalnızca etkin olarak kullanılan uygulama örneklerine göndermeniz önerilir. Bu, özellikle çok sayıda abonesi olan konulara düzenli olarak mesaj gönderiyorsanız önemlidir. Bu abonelerin bir kısmı etkin değilse teslimat istatistikleriniz üzerinde zaman içinde önemli bir etkisi olabilir.
Mesajları jetona hedeflemeden önce şunları göz önünde bulundurun:
- Google Analytics, BigQuery'de yakalanan veriler veya diğer izleme sinyalleri jetonun etkin olduğunu gösteriyor mu?
- Önceki teslimat denemeleri bir süre boyunca sürekli olarak başarısız oldu mu?
- Kayıt jetonu, sunucularınızda son bir ay içinde güncellendi mi?
- Android cihazlarda FCM Veri API,
droppedDeviceInactive
nedeniyle ileti yayınlama hatalarının yüksek bir yüzdesini mi bildiriyor?
Teslimat hakkında daha fazla bilgi için Mesaj teslimini anlama başlıklı makaleyi inceleyin.