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 kaynakları boşa harcadığınızı fark edebilirsiniz. Bu durum, Firebase konsolunda bildirilen ileti teslimi verilerini veya BigQuery'ye aktarılan verileri etkileyebilir ve teslim oranlarında önemli (ancak aslında geçerli olmayan) bir düşüş olarak görünebilir. Bu kılavuzda, etkili ileti hedefleme ve geçerli yayın raporlaması sağlamak için alabileceğ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'ya bağlanmamış etkin olmayan cihazlarla ilişkili jetonlardır. Zaman geçtikçe cihazın FCM ağına tekrar bağlanma olasılığı azalır. Bu eski jetonlar için ileti gönderme ve konu dağıtma işlemlerinin hiçbir zaman teslim edilmesi olası değildir.
Bir jetonun eski hale gelmesinin çeşitli nedenleri olabilir. Örneğin, jetonun ilişkilendirildiği cihaz kaybolmuş, hasar görmüş veya depolamaya konup unutulmuş olabilir.
Eski jetonlar 270 gün boyunca kullanılmadığında FCM bunları geçerliliği sona ermiş jetonlar olarak kabul eder. Jetonun süresi dolduğunda FCM, jetonu geçersiz olarak işaretler ve jetona gönderilen iletileri reddeder. Ancak cihaz tekrar bağlandığında ve uygulama açıldığında FCM, uygulama örneği için yeni bir jeton verir.
Temel en iyi uygulamalar
Gönderme isteklerini programatik olarak oluşturmak için FCM API'lerini kullanan tüm uygulamalarda uygulamanız gereken bazı temel yöntemler vardır. Başlıca en iyi uygulamalar şunlardır:
- FCM'dan kayıt jetonlarını alıp sunucunuzda saklayın. Sunucunun önemli bir görevi, her istemcinin jetonunu takip etmek ve etkin jetonların güncel bir listesini tutmaktır. Kodunuzda ve sunucularınızda 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 artık geçerli saymadığı jetonları kaldırmanın yanı sıra, jetonların eski hale geldiğine dair diğer işaretleri de izleyip bunları proaktif olarak kaldırmak isteyebilirsiniz. Bu kılavuzda, bu hedefe ulaşmak için kullanabileceğiniz bazı seçenekler ele alınmaktadır.
Kayıt jetonlarını alma ve depolama
Uygulamanızın ilk başlatılmasında FCM SDK, istemci uygulaması örneği için bir kayıt jetonu oluşturur. Bu, API'den gönderilen hedeflenmiş isteklerde eklemeniz veya konuları hedeflemek için konu aboneliklerine eklemeniz gereken jetondur.
Uygulamanızın bu jetonu ilk başlatma sırasında almasını ve zaman damgasıyla birlikte uygulama sunucunuza kaydetmesini önemle tavsiye ederiz. Bu zaman damgası, FCM SDK'ları tarafından sağlanmadığı için kodunuz ve sunucularınız tarafından uygulanmalıdır.
Ayrıca, jetonu sunucuya kaydetmek ve zaman damgasını her değiştiğinde (ör. aşağıdaki durumlarda) güncellemek önemlidir:
- Uygulama yeni bir cihaza geri yüklendi
- Kullanıcı, uygulamanın yüklemesini kaldırır veya uygulamayı yeniden yüklerse
- Kullanıcı, uygulama verilerini temizlerse
- Uygulama, mevcut jetonunun süresi FCM dolduktan sonra tekrar etkin hale gelir.
Örnek: Cloud Firestore içinde jetonları ve zaman damgalarını saklayın
Örneğin, fcmTokens
adlı bir koleksiyonda jetonları 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ı saklar. Bu Kotlin örneğinde gösterildiği gibi set
işlevini 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)
}
Bir jeton her 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()
}
}
Jetonun güncelliğini koruma ve eski jetonları kaldırma
Jetonun yeni mi yoksa eski mi olduğunu belirlemek her zaman kolay değildir. Tüm durumları kapsamak için jetonları eski olarak kabul edeceğiniz bir eşik belirlemeniz gerekir. Varsayılan olarak, FCM bir jetonun uygulama örneği bir ay boyunca bağlanmamışsa jetonu eski olarak kabul eder. Bir aydan eski jetonlar büyük olasılıkla 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 kriterleri belirlemek size kalmıştır.
FCM arka ucundan gelen geçersiz jeton yanıtlarını algılama
FCM'dan gelen geçersiz jeton yanıtlarını tespit ettiğinizden ve sisteminizden geçersiz olduğu veya süresinin dolduğu bilinen tüm kayıt jetonlarını silerek yanıt verdiğinizden emin olun. HTTP v1 API'sinde bu 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 yükünün geçerli olduğundan eminseniz ve hedeflenen bir jeton için bu yanıtlardan birini alırsanız bu jetonun kaydını silebilirsiniz. Bu jeton bir daha asla geçerli olmayacaktır. Örneğin, Cloud Firestore içindeki geçersiz jetonları silmek için aşağıdakine benzer 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 jetonun süresi 270 gün sonra dolarsa veya istemci açıkça kaydını silerse geçersiz jeton yanıtı döndürür. Eskimeyi kendi tanımlarınıza göre daha doğru bir şekilde izlemeniz gerekiyorsa eski kayıt jetonlarını proaktif olarak kaldırabilirsiniz.
Jetonları düzenli olarak güncelleme
Sunucunuzdaki tüm kayıt jetonlarını düzenli olarak alıp güncellemenizi öneririz. Bunun için:
- Uygun API çağrısını (ör. Apple platformları için
token(completion):
veya Android içingetToken()
) kullanarak istemci uygulamanıza geçerli jetonu almak için uygulama mantığı ekleyin ve ardından geçerli jetonu depolama için uygulama sunucunuza gönderin (zaman damgasıyla birlikte). Bu, tüm istemcileri veya jetonları kapsayacak şekilde yapılandırılmış aylık bir iş olabilir. - Jetonun değişip değişmediğine bakılmaksızın, jetonun zaman damgasını düzenli aralıklarla güncellemek için sunucu mantığı ekleyin.
WorkManager kullanılarak jetonların güncellenmesiyle ilgili Android mantığı örneği için Firebase blogundaki Cloud Messaging Jetonlarını Yönetme başlıklı makaleyi inceleyin.
Hangi zamanlama düzenini kullanırsanız kullanın, jetonları düzenli olarak güncellediğinizden emin olun. Ayda bir kez 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 yenileme işlemiyle, etkin olmayan cihazların tekrar etkin hale geldiğinde kayıtlarının yenilenmesini de sağlarsınız. Yenileme işlemini haftada bir kereden daha sık yapmanın bir avantajı yoktur.
Eski kayıt jetonlarını kaldırma
Bir cihaza mesaj göndermeden önce cihazın kayıt jetonunun zaman damgasının, eski verilerin geçerlilik süresi içinde olduğundan emin olun. Örneğin, Cloud Functions for Firebase gibi bir eskime penceresi süresi içinde zaman damgasının geçerli olduğundan emin olmak için günlük bir kontrol çalıştırmak üzere const
EXPIRATION_TIME = 1000 * 60 * 60 * 24 * 30;
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ın konularla ilişkisini kaldırma
Konuları kullanıyorsanız eski jetonların, abone oldukları konulardan kaydını da silmek isteyebilirsiniz. Bu işlem iki adımdan oluşur:
- Uygulamanız, konulara ayda bir kez ve kayıt jetonu her değiştiğinde yeniden abone olmalıdır. Bu sayede, uygulamalar tekrar etkin olduğunda aboneliklerin otomatik olarak yeniden gösterildiği bir kendi kendini onaran çözüm oluşturulur.
- Bir uygulama örneği bir ay boyunca (veya kendi eski veri pencereniz) boşta kalırsa FCM arka ucundan jeton-konu eşlemesini silmek için Firebase Admin SDK'yı kullanarak bu örneğin konu aboneliğini iptal etmeniz gerekir.
Bu iki adımın avantajı, daha az eski jeton olduğundan dağıtımlarınızın daha hızlı gerçekleşmesi ve eski uygulama örneklerinizin tekrar etkin olduklarında otomatik olarak yeniden abone olmasıdır.
Teslimat başarısını ölçme
Mesaj teslimiyle ilgili en doğru resmi elde etmek için yalnızca etkin olarak kullanılan uygulama örneklerine mesaj göndermeniz önerilir. Bu durum, özellikle çok sayıda abonesi olan konulara düzenli olarak ileti gönderiyorsanız önemlidir. Bu abonelerin bir kısmı aslında etkin değilse zaman içinde teslimat istatistikleriniz önemli ölçüde etkilenebilir.
İletileri bir jetonu 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?
- Daha önceki teslimat denemeleri belirli 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 Data API,
droppedDeviceInactive
nedeniyle yüksek oranda ileti teslim hatası bildiriyor mu?
Teslimat hakkında daha fazla bilgi için İleti teslimini anlama başlıklı makaleyi inceleyin.