← Blog'a Dön

Push Notification Nasıl Çalışır?

Push Notification Nasıl Çalışır?
Uygulamanız Kapalıyken Gelen Mesaj
Telefonu ceple bıraktınız. Ekran kapalı, uygulamalar çalışmıyor. Birkaç dakika sonra ekran aydınlanıyor, bir bildirim geliyor: "Mesajınız görüldü."
Bu nasıl mümkün? Uygulama çalışmıyorken sunucu uygulamaya nasıl ulaştı? Telefon nasıl uyandı?
Bu soruların cevabı hem mimari hem de mühendislik açısından son derece zarif bir çözümde yatıyor.

Temel Sorun: Sunucu Telefona Ulaşamaz
İnternette iletişim genellikle şu yönde işler: İstemci sunucuya istek gönderir, sunucu yanıtlar. Bu istemci-başlatmalı (client-initiated) modeldir ve HTTP bu modele göre çalışır.
Ama push notification'da durum tersidir. Sunucu, kendi başına bir şey olduğunda istemciye — yani telefona — bunu bildirmek ister. Sunucu-başlatmalı (server-initiated) bir iletişim gerekiyor.
Bu neden zordur?
Telefonların büyük çoğunluğu dinamik IP adreslerine sahiptir. IP adresi sürekli değiştiğinden sunucu "şu adrese bağlan" diyemez. Üstelik telefon bir ağ geçidinin (NAT) arkasındadır ve dışarıdan doğrudan erişilemez. Ve uygulama çalışmıyorsa dinleyecek kimse yoktur.
Bu sorunu çözmek için uygulamanın sürekli arka planda çalışması ve sunucuya bağlı kalması düşünülebilir. Ama her uygulamanın bunu yapması hem pil tüketimini mahveder hem de sistemi tıkar. Yüzlerce uygulama yüzlerce farklı sunucuya kalıcı bağlantı tutarsa telefon hızla devre dışı kalır.
Çözüm tek ve merkezi bir bağlantı noktasıdır.

FCM: Firebase Cloud Messaging
Google'ın bu soruna sunduğu çözüm FCM (Firebase Cloud Messaging) — önceki adıyla GCM, Google Cloud Messaging'dir.
FCM'nin mimarisini anlamak için üç aktörü tanımak gerekir.
FCM Sunucusu Google'ın kendi altyapısında çalışan merkezi bir sistemdir. Tüm Android cihazlarıyla kalıcı ve verimli bir bağlantı sürdürür.
Uygulama Sunucunuz bildirim göndermek istediğinizde FCM Sunucusuyla iletişim kurar. Kendi sunucunuz doğrudan telefona ulaşmaz — FCM'ye "şu cihaza şu bildirimi gönder" der.
Android Cihaz FCM Sunucusuyla tek bir kalıcı bağlantı sürdürür. Bu bağlantı işletim sistemi düzeyindedir ve tek bir uygulama değil, sistem servisi üzerinden yönetilir. Tüm uygulamalar bu tek bağlantıyı paylaşır.
Bu tasarım pil verimliliğinin anahtarıdır. Yüzlerce ayrı bağlantı yerine tek bir sistem bağlantısı.

FCM Token: Cihazın Posta Kutusu
Bir cihaza bildirim göndermek için o cihazın adresi bilinmelidir. Bu adres FCM token'dır.
Uygulama ilk kurulduğunda ya da yeniden yüklendiğinde FCM SDK, Google'ın sunucularından cihaza özgü bir token üretir. Bu token uzun ve rastgele bir karakter dizisidir ve o cihaz-uygulama kombinasyonunu benzersiz biçimde tanımlar.
Bu token uygulama sunucunuza gönderilmeli ve orada saklanmalıdır. Bir kullanıcıya bildirim göndermek istediğinizde veritabanından o kullanıcının token'ını alır ve FCM'ye iletirsiniz.
Token'lar değişebilir. Kullanıcı uygulamayı silip yeniden kurduğunda, cihazı sıfırladığında ya da FCM verilerini temizlediğinde token yenilenir. Bu yüzden uygulama her açıldığında güncel token kontrol edilmeli ve değişmişse sunucuya bildirilmelidir.

Bildirim Yolculuğu: Adım Adım
Bir bildirim gönderildiğinde yaşanan süreci başından sonuna izleyelim.
Önce tetikleyici olay oluşur. Bir kullanıcı size mesaj gönderdi, siparişinizin durumu güncellendi, bir indirim başladı. Bu olay uygulama sunucunuzda tespit edilir.
Uygulama sunucunuz FCM API'sine bir istek gönderir. Bu istek hedef cihazın token'ını, bildirim başlığını, bildirim metnini ve varsa ekstra veri yükünü içerir. İstek kimlik doğrulamalıdır — yalnızca yetkili sunucular FCM üzerinden bildirim gönderebilir.
FCM Sunucusu bu isteği alır, hedef token'ı kayıtlarında arar ve ilgili cihazla olan kalıcı bağlantı üzerinden bildirimi iletir.
Cihaz uyanır. Ekran kapalı ve tüm uygulamalar durmuş olsa bile FCM bağlantısı sistem düzeyinde aktiftir. Gelen bildirim işletim sistemi tarafından karşılanır.
Son olarak bildirim gösterilir ya da işlenir. Uygulamanız arka plandaysa sistem otomatik olarak bildirim çubuğunda gösterir. Uygulamanız ön plandaysa bildirim doğrudan uygulamaya iletilir ve siz istediğiniz biçimde işlersiniz.

İki Farklı Mesaj Türü
FCM iki farklı mesaj türü sunar ve bu ayrım önemlidir.
Notification Message görsel bir bildirim göstermek için tasarlanmıştır. Başlık, metin, ikon ve ses bilgisi içerir. Uygulama arka plandayken sistem bu mesajı otomatik olarak bildirim çubuğunda gösterir. Kullanıcı bildirime dokunduğunda uygulama açılır.
Data Message ise görsel bildirim içermez, yalnızca veri taşır. Uygulama arka planda ya da kapalıyken bu mesaj uygulamanın bir servisine iletilir. Uygulama bu veriyi alır ve ne yapacağına kendisi karar verir. Belki sessiz bir senkronizasyon yapar, belki yerel bir bildirim gösterir, belki yalnızca veriyi günceller.
Bu iki türü birleştirmek de mümkündür. Hem görsel bildirim hem de ek veri taşıyan karma mesajlar kullanılabilir.

Uygulama Durumuna Göre Farklı Davranış
Bildirimin nasıl işlendiği uygulamanın o anki durumuna göre değişir.
Uygulama ön plandayken tüm bildirimler doğrudan uygulamanızın onMessageReceived metoduna düşer. Sistem otomatik hiçbir şey göstermez. Ne yapılacağına siz karar verirsiniz. Kullanıcı zaten uygulamayı kullanıyorsa bildirim çubuğunda göstermek yerine uygulama içinde bir banner ya da badge güncellemesi çok daha iyi bir deneyim sunar.
Uygulama arka plandayken notification message'lar sistem tarafından otomatik gösterilir ve onMessageReceived çağrılmaz. Data message'lar ise uygulamanıza iletilir ve sessizce işlenebilir.
Uygulama tamamen kapalıyken notification message'lar yine sistem tarafından gösterilir. Kullanıcı bildirime dokunduğunda uygulama başlatılır ve intent içinde bildirim verisi iletilir.

Bildirim İzinleri: Android 13 Değişikliği
Android 13 ile birlikte push notification davranışı önemli biçimde değişti.
Bu versiyondan önce uygulamalar kurulduğunda otomatik olarak bildirim gönderme iznine sahip oluyordu. Kullanıcı bunu sistem ayarlarından kapatabiliyordu ama varsayılan açıktı.
Android 13 ile birlikte POST_NOTIFICATIONS izni zorunlu runtime izni haline geldi. Uygulama kurulduğunda bu izin otomatik verilmez. Uygulamanın kullanıcıdan açıkça bu izni istemesi gerekir. Kullanıcı reddederse bildirim gönderilemez.
Bu değişiklik bildirim stratejinizi doğrudan etkiler. İzni ne zaman isteyeceğiniz, nasıl açıklayacağınız ve kullanıcı reddettiğinde ne yapacağınız artık birer tasarım kararıdır. Uygulama açılır açılmaz izin istemek yerine bildirimlerin gerçekten değer kattığı bir anda istemek çok daha yüksek kabul oranı sağlar.

Geliştirici Perspektifinden Bakış
Push notification sistemini doğru kurmak birkaç kritik kararı içerir.
Token yönetimini sağlam yapın. Token değiştiğinde sunucunuzun güncel token'ı bilmesi gerekir. Güncel olmayan token'a gönderilen bildirimler sessizce kaybolur. FCM, geçersiz token'lar için hata kodu döndürür ve sunucunuz bu token'ları veritabanından silmelidir.
Bildirim içeriğini değerli tutun. Kullanıcılar gereksiz ya da alakasız bildirimler nedeniyle izni geri alır. Her bildirim kullanıcıya gerçek değer sunmalıdır. Bildirim stratejisi bir teknik karar kadar bir ürün kararıdır.
Yerel bildirimi FCM bildirimiyle karıştırmayın. Yerel bildirimler sunucu gerektirmeden doğrudan cihazda oluşturulur. Hatırlatıcılar, zamanlayıcılar, uygulama içi uyarılar için yerel bildirimler kullanılır. FCM yalnızca sunucu tarafından tetiklenen durumlar içindir.
Ve her zaman uygulama ön planda durumunu ayrıca ele alın. Sistem otomatik gösterdiği için arka plan senaryosu kolaydır. Ön plan senaryosu ise her zaman özel işleme gerektirir ve sıklıkla göz ardı edilir.