FCM API'leri kullanarak gönderme isteklerini programatik olarak oluşturuyorsanız zamanla, eski kayıtları olan etkin olmayan cihazlara mesaj göndererek kaynakları boşa harcadığınızı fark edebilirsiniz. Bu durum, Firebase konsolunda bildirilen mesaj teslimi verilerini veya BigQuery'ye aktarılan verileri etkileyebilir. Bu veriler, teslim oranlarında önemli (ancak geçerli olmayan) bir düşüş olarak gösterilir. Bu rehberde, etkili mesaj hedefleme ve geçerli teslimat raporlaması sağlamak için alabileceğiniz bazı önlemler ele alınmaktadır.
Eski ve süresi dolmuş kayıtlar
Eski kayıtlar, bir aydan uzun süredir FCM'ya bağlanmamış etkin olmayan cihazlarla ilişkilendirilir. Zaman geçtikçe cihazın FCM'ya tekrar bağlanma olasılığı azalır. Bu eski kayıtlar için ileti gönderme ve konu dağıtma işlemlerinin hiçbir zaman teslim edilmesi olası değildir.
Bir kaydın eski hale gelmesinin birkaç nedeni vardır. Örneğin, kaydın ilişkilendirildiği cihaz kaybolmuş, hasar görmüş veya depoya konup unutulmuş olabilir.
Android'de, 270 gün boyunca etkin olmayan kayıtlar FCM tarafından süresi dolmuş olarak kabul edilir ve çöp toplama işlemine tabi tutulur. Bir kayıtın süresi dolduğunda FCM, kaydı geçersiz olarak işaretler ve bu kayda gönderilen iletileri reddeder. Firebase yükleme kimliklerinin (FID'ler) kendilerinin FCM tarafından değil, Firebase Installations hizmeti (FIS) tarafından yönetildiğini unutmayın. Bir cihazın tekrar bağlanması ve uygulamanın, kaydı çöp toplama işlemine tabi tutulduktan sonra açılması gibi nadir durumlarda, istemci uygulaması FIS'ten alınan FID'yi kullanarak FCM ile tekrar kaydolur. FID'nin değişebileceğini unutmayın. FID'lerin ne zaman yeniden verildiğiyle ilgili ayrıntılar için Firebase yüklemelerini yönetme başlıklı makaleyi inceleyin.
iOS gibi diğer platformlarda FCM, temel push hizmetine (ör.APNs) bağlıdır. Bu hizmette, 270 günlük hareketsizlik süresine dayalı aynı geçerlilik süresi yoktur. Kayıtların güncelliğini korumanızı ve eski kayıtları kaldırmanızı öneririz.
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:
- Firebase yükleme kimliklerini (FID'ler) alma FCMve bunları uygulama sunucunuzda depolama Sunucunun önemli bir rolü, her istemcinin kayıtlı FID'sini takip etmek ve etkin FID'lerin güncel bir listesini tutmaktır. Veritabanınızda bir kayıt zaman damgası uygulamanızı ve kayıt yüklendiğinde bu zaman damgasını güncellemenizi önemle tavsiye ederiz.
- Kayıtların güncelliğini koruyun ve eski kayıtları kaldırın. FCM artık geçerli kabul etmediği kayıtları kaldırmanın yanı sıra kayıtların eski hale geldiğine dair diğer işaretleri de izleyip bunları proaktif olarak kaldırabilirsiniz. Bu kılavuzda, bu hedefe ulaşmak için kullanabileceğiniz bazı seçenekler ele alınmaktadır.
Firebase yükleme kimliklerini alma ve depolama
Uygulamanız ilk kez başlatıldığında FCM SDK'sı, uygulama örneğini FCM ile kaydeder ve bir Firebase yükleme kimliği (FID) döndürür. Bu, API'den gönderilen hedefli isteklerde eklemeniz gereken veya konu abonelikleri için kullanmanız gereken tanımlayıcıdır.
FID'yi her yüklendiğinde zaman damgasıyla birlikte uygulama sunucunuza kaydetmenizi önemle tavsiye ederiz. Her yükleme isteğindeki zaman damgasını güncelleyerek sunucunuz, uygulama örneğinin en son ne zaman açıldığını ve FCM arka ucuyla ne zaman başarıyla senkronize edildiğini bilir.
Otomatik başlatma özelliğinin etkinleştirilip devre dışı bırakılmasına (desteklenmemesi dahil) bağlı olarak kayıt ve güncellemeleri aşağıdaki şekilde yapmanız gerekir:
- (Önerilen) Otomatik başlatma etkinleştirildiğinde: SDK, kaydı otomatik olarak güncel tutar ve değişiklikleri izler.
onRegistered()geri çağırma işlevi, uygulama başlatılırken rutin senkronizasyonlarda ve FID değişiklikleri gerçekleştiğinde düzenli olarak çağrılır. FID'yi sunucunuza yüklemek ve mevcut zaman damgasını kaydetmek için bu geri çağırmayı uygulamanız yeterlidir. - Otomatik başlatma devre dışı bırakıldığında:
onRegistered()geri çağırma işlevi başlangıçta otomatik olarak çağrılmaz. Kayıtları izlemek ve güncel tutmak için uygulama başlatıldığındaregister()'ı çağırın. Örneğin, Android'de ana etkinliğinonCreate()bölümünde. Başarılı bir arama, FID kullanılarak FCM kayıt sürecini tetikler ve FID'yionRegistered()geri arama işlevinize iletir. Böylece uygulamanız FID'yi yükleyebilir ve sunucunuzdaki zaman damgasını güncelleyebilir.
Örnek: Cloud Firestore içinde mağaza FIDs'lerini ve zaman damgalarını saklayın.
Örneğin, Cloud Firestore kullanarak FID'leri fcmRegistrations adlı bir koleksiyonda saklayabilirsiniz. Koleksiyondaki her doküman kimliği bir kullanıcı kimliğine karşılık gelir ve dokümanda geçerli FID ile son güncelleme zaman damgası saklanır. Bu Kotlin örneğinde gösterildiği gibi set işlevini kullanın:
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)
}
Firebase yükleme kimliği her başarıyla kaydedildiğinde veya güncellendiğinde onRegistered() geri çağırma işlemi başlatılır. FID'yi yüklemek ve zaman damgasını güncellemek için bu geri çağırmayı uygulamanız gerekir:
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)
}
Otomatik başlatmanın devre dışı bırakıldığı durumlarda, kayıt akışını ve FID'nin onRegistered() üzerinden teslimini tetiklemek için uygulama başlatıldığında (ör. onCreate() içinde) register() işlevini çağırın:
// 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)
}
}
Kayıtların güncelliğini koruma ve eski kayıtları kaldırma
Bir kaydın yeni mi yoksa eski mi olduğunu belirlemek her zaman kolay değildir. Tüm durumları kapsamak için kayıtları eski olarak kabul edeceğiniz bir eşik belirlemelisiniz. Varsayılan olarak FCM, uygulama örneği bir aydır bağlanmamışsa kaydı eski olarak kabul eder. Bir aydan eski kayıtlar büyük olasılıkla etkin olmayan cihazlara aittir. Etkin cihazlar kayıtları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 yanıtları algılama
FCM'dan gelen geçersiz yanıtları tespit ettiğinizden ve sisteminizden geçersiz olduğu veya süresinin dolduğu bilinen tüm kayıtları silerek yanıt verdiğinizden emin olun. HTTP v1 API'sinde bu hata mesajları, gönderme isteğinizin geçersiz veya süresi dolmuş kayıtları hedeflediğini gösterebilir:
UNREGISTERED(HTTP 404)INVALID_ARGUMENT(HTTP 400)
Mesaj yükünün geçerli olduğundan eminseniz ve hedeflenen bir kayıt için bu yanıtlardan birini alırsanız bu kaydın kaydını silebilirsiniz. Bu kayıt bir daha geçerli olmayacaktır. Örneğin, Cloud Firestore içindeki geçersiz kayıtları silmek için aşağıdaki gibi bir işlev dağıtıp çalıştırabilirsiniz:
// 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, Android cihaz kaydı 270 gün boyunca işlem yapılmadığı için sona erdiyse veya istemci açıkça kaydı silmişse geçersiz bir yanıt döndürür. Eskimeyi kendi tanımlarınıza göre daha doğru şekilde izlemeniz gerekiyorsa eski kayıtları proaktif olarak kaldırabilirsiniz.
Kayıtları düzenli olarak güncelleme
Kayıtlarınız FID'lere veya eski kayıt jetonlarına dayalı olsun ya da olmasın, sunucunuz her yükleme isteğinde veritabanınızdaki kayıt zaman damgasını her zaman güncellemelidir. Bu zaman damgası, uygulama yüklemesi için bir sinyal görevi görür. İstemcinin uygulamayı başarıyla açtığını ve FCM arka ucuyla senkronize olduğunu gösterir. Kullandığınız API'lere bağlı olarak uygun stratejiyi uygulayın:
Firebase yükleme kimliği API'leri (önerilir)
FID API'lerini kullanan istemci uygulamaları için kayıtları almak veya yenilemek üzere istemci uygulamanızda düzenli olarak arka plan görevleri planlamanız gerekmez. SDK, otomatik başlatma sırasında yenileme işlemlerini otomatik olarak gerçekleştirir ve uygulama başlatılırken rutin senkronizasyonlarda onRegistered() geri çağırma işlevinize düzenli olarak doğru geçerli FID'yi iletir.
Sunucunuzu güncel tutmak için Firebase yükleme kimliklerini alma ve depolama başlıklı makalede ayrıntılı olarak açıklanan başlangıç yükleme stratejilerini uygulayın:
- Otomatik başlatma etkin: SDK, uygulama başlatıldığında rutin senkronizasyonlar sırasında en son FID'nin sunucunuza gönderilmesini otomatik olarak sağlar.
- Otomatik başlatma devre dışı veya desteklenmiyor: Kayıt sırasını zorlamak ve FID'nin
onRegistered()geri çağırma işlevinize teslim edilmesini tetiklemek için uygulama başlatıldığında (örneğin, Android'de ana etkinliğinonCreate()içinde)register()işlevini çağırın.
Bu stratejiler, sunucunuzun her zaman en son etkin FID'ye sahip olmasını ve başarısız yüklemelerden otomatik olarak kurtulabilmesini sağlayarak uygulamayı oldukça esnek hale getirir.
Kullanımdan kaldırılan kayıt jetonu API'leri
Eski kayıt jetonlarını kullanıyorsanız istemci SDK'sı, rutin senkronizasyonlarda yenilemeleri otomatik olarak yönetmez. Bu nedenle, 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 mevcut jetonu almak üzere istemci uygulamanıza uygulama mantığı ekleyin ve ardından mevcut jetonu depolama için uygulama sunucunuza (zaman damgasıyla birlikte) gönderin. Bu, tüm müşterileri 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 eski jetonların güncellenmesiyle ilgili Android mantığı örneği için Firebase blogundaki Cloud Messaging Jetonlarını Yönetme başlıklı makaleye bakın.
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 yenilemeyi yaparak etkin olmayan cihazların tekrar etkin hale geldiğinde kayıtlarını yenilemesini de sağlarsınız. Yenileme işlemini haftada bir kereden daha sık yapmanın bir avantajı yoktur.
Eski kayıtları kaldırma
Bir cihaza mesaj göndermeden önce cihazın kayıt zaman damgasının, eski verilerin geçerlilik süresi içinde olduğundan emin olun. Örneğin, zaman damgasının const
EXPIRATION_TIME = 1000 * 60 * 60 * 24 * 30; gibi tanımlanmış bir eskime penceresi süresi 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 kayıtları kaldırabilirsiniz:
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(); });
});
Eski kayıtları konulardan çıkarma
Konuları kullanıyorsanız eski kayıtları, abone oldukları konulardan da kaldırmak isteyebilirsiniz. Bu işlem iki adımdan oluşur:
- Uygulamanız, Firebase yükleme kimliği (FID) her değiştiğinde konulara yeniden abone olmalıdır. Bu sayede, bir uygulama tekrar etkin hale geldiğinde abonelikler otomatik olarak yeniden gösterilir.
- Bir uygulama örneği bir ay boyunca (veya kendi eskime aralığınız) boşta kalırsa Firebase Admin SDK'sını kullanarak Firebase yükleme kimliğinin konu eşlemesini FCM arka ucundan silmek için bu örneğin konu aboneliğini iptal etmeniz gerekir.
Bu iki adımın avantajı, daha az eski kayıt olduğundan fanout işlemlerinizin daha hızlı gerçekleşmesi ve eski uygulama örneklerinizin tekrar etkin hale geldiklerinde 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 mesaj gönderiyorsanız önemlidir. Bu abonelerin bir kısmı aslında etkin değilse zaman içinde teslimat istatistikleriniz önemli ölçüde etkilenebilir.
Mesajları bir uygulama örneğini hedefleyecek şekilde ayarlamadan önce şunları göz önünde bulundurun:
- Google Analytics, BigQuery'de yakalanan veriler veya diğer izleme sinyalleri, kaydın etkin olduğunu gösteriyor mu?
- Önceki teslimat denemeleri belirli bir süre boyunca sürekli olarak başarısız oldu mu?
- Firebase yükleme kimliği, sunucularınızda son bir ay içinde güncellendi mi?
- Android cihazlarda FCM Data API,
droppedDeviceInactivenedeniyle yüksek oranda mesaj teslimi başarısızlığı bildiriyor mu?
Teslimat hakkında daha fazla bilgi için Mesaj teslimatını anlama başlıklı makaleyi inceleyin.