Push notifications: APNs vs FCM și cum măsori opt-in
APNs livrează pe iOS, FCM abstractizează Android și Web. Regulile de permisiune, tipurile de mesaj și metricile de urmărit pentru push notifications.
Cuprins
- Cum funcționează push notifications (arhitectura APNs și FCM)?
- Care sunt regulile de permisiune pe iOS și Android?
- Care sunt tipurile de push: transactional vs marketing vs silent?
- Ce metrici urmărești pentru a evalua succesul (opt-in rate, CTR, frequency cap)?
- Care sunt capcanele de implementare (silent push, payload size, retry, badge counts)?
Push notifications sunt mesaje livrate de un server către un device fără ca aplicația să fie deschisă, prin infrastructuri dedicate: APNs (Apple Push Notification Service) pentru iOS și macOS, și FCM (Firebase Cloud Messaging) pentru Android, Web și ca strat de abstractizare peste APNs. Mecanismul permite contactul asincron cu utilizatorul, de la confirmare de comandă la alertă de stoc.
Față de SMS sau e-mail, livrarea trece obligatoriu prin serverele Apple sau Google. Poți trimite un mesaj corect format și totuși să nu ajungă pe device: permisiunea lipsă, device offline cu TTL expirat sau payload prea mare.
Cum funcționează push notifications (arhitectura APNs și FCM)?
Fluxul are aceiași pași indiferent de platformă. La instalarea aplicației, sistemul de operare generează un device token unic, identificatorul dispozitivului pe infrastructura de push. Aplicația trimite token-ul la serverul tău, unde îl stochezi asociat cu contul utilizatorului. Când vrei să trimiți o notificare, serverul tău face o cerere HTTPS autentificată către APNs sau FCM, care livrează mesajul pe device-ul identificat de token.
APNs și FCM diferă în câteva puncte:
- Autentificare server-side. APNs acceptă două metode: certificate-based (fișier
.p12rotit anual) și token-based (JWT semnat cu o cheie privată Ed25519, fără expirare forțată, recomandat). FCM folosește un service account Google, cu token OAuth2 generat la fiecare cerere sau cached. - Structura payload-ului. APNs are câmpuri native (
alert,badge,sound,content-availablepentru silent push). FCM normalizează toate acestea în câmpuri proprii (notification,data,apns) și permite să trimiți același payload la iOS, Android și Web cu o singură cerere, lăsând FCM să traducă per platformă. - Livrare finală. Pe iOS, livrarea trece mereu prin APNs, chiar dacă mesajul a intrat prin FCM. FCM este un proxy, nu o alternativă la APNs pentru device-uri Apple.
- TTL și retry. Ambele sisteme acceptă un TTL configurabil (Time to Live). Dacă device-ul e offline și TTL-ul expiră, mesajul e abandonat, nu retransmis. FCM expune un câmp explicit
ttl; APNs acceptă header-ulapns-expirationcu un timestamp Unix. Pentru notificări transacționale cu context scurt (promoție valabilă azi), TTL-ul trebuie setat explicit; valoarea implicită poate fi ore sau zile.
Biblioteci ca OneSignal sau Expo Notifications abstractizează fluxul, dar sub ele tot APNs și FCM lucrează. Alegerea unei biblioteci nu elimină nevoia de a înțelege transportul.
Care sunt regulile de permisiune pe iOS și Android?
Pe iOS, utilizatorul aprobă explicit notificările la prima deschidere (din iOS 8, 2014). Sistemul afișează dialogul nativ o singură dată; dacă refuză, nu mai apare automat. Momentul contează: dacă ceri permisiunea la instalare, fără context, rata de aprobare e mai mică decât dacă o ceri după ce utilizatorul a văzut prima valoare concretă din aplicație.
Pe Android 12 și mai vechi, notificările sunt activate implicit la instalare, fără dialog. Din Android 13 (API level 33, 2022), comportamentul este aliniat cu iOS: permisiunea se cere explicit prin POST_NOTIFICATIONS. Dacă stochezi consimțământul pentru notificări de marketing, înregistrează momentul și metoda; notificările tranzacționale (confirmare comandă, alertă de securitate) au cerințe de consimțământ diferite față de cele promoționale.
Care sunt tipurile de push: transactional vs marketing vs silent?
Trei categorii cu logică de livrare și reguli de consimțământ distincte:
- Transactional. Declanșate de o acțiune a utilizatorului sau a sistemului: comandă plasată, status schimbat, autentificare nouă pe cont, alertă de preț. Toleranță ridicată din partea utilizatorului, relevanță ridicată. Sunt cele mai ușor de acceptat și cel mai greu de abuzat.
- Marketing. Promoții, campanii, reactivare utilizatori inactivi. Toleranță scăzută; un utilizator care primește prea multe dezactivează permisiunea. Regulile GDPR sunt mai stricte: stochezi consimțământul explicit, îi dai utilizatorului opțiunea de opt-out granular (nu doar dezactivare completă), respecți frecvența pe care o indică el.
- Silent push (background updates). Fără alertă vizibilă, trezesc aplicația în fundal să preîncarce date. Utile pentru sincronizare de conținut, actualizare de cache, prefetch înaintea deschiderii. APNs limitează la trei livrări pe oră per device prin câmpul
content-available: 1; depășirea face ca mesajele suplimentare să fie refuzate sau ignorate. FCM are echivalentul prin mesaje cu prioritate mică (priority: "normal").
Separarea logică a celor trei tipuri în codul serverului tău, nu în UI, permite analytics distinct și frequency cap diferențiat pe canal. Un utilizator care a dezactivat marketingul nu ar trebui să piardă notificările tranzacționale.
Ce metrici urmărești pentru a evalua succesul (opt-in rate, CTR, frequency cap)?
Patru metrici de bază calculabile din SDK-urile de push sau din evenimentele trimise la backend:
- Opt-in rate. Procentul de instalări care aprobă permisiunea. Pe iOS, valorile tipice citate de furnizorii de push (Airship, OneSignal) sunt în jur de 50-70%; pe Android mai vechi de 13, permisiunea era implicită, deci ratele erau peste 80%. Sunt cifre orientative, nu valori garantate; rata ta depinde de momentul în care ceri permisiunea și de contextul construit înainte.
- CTR per tip. Procentul de notificări livrate la care utilizatorul dă click. Range-ul publicat de platformele de push marketing este de obicei 2-8%, cu tranzacționalele peste marketing. Calculezi separat per tip, nu agregat.
- Delivery rate. Procentul de mesaje trimise la APNs/FCM care au ajuns pe device. Diferența față de 100% vine din device-uri offline cu TTL expirat sau token-uri invalide (dezinstalare). Curăță token-urile invalide periodic.
- Frequency cap respectat. Dacă rata de opt-out crește când frecvența crește, ai depășit toleranța. Cap-ul se setează pe server, nu îl lăsa SDK-ului.
Evenimentele de livrare, click și opt-out sunt telemetrie la fel ca orice alt eveniment din aplicație. La crawlerra le tratăm ca semnale de produs în același stack de observabilitate în care intră și restul metricilor, corelate cu alte semnale de engagement rate.
Care sunt capcanele de implementare (silent push, payload size, retry, badge counts)?
- Token-uri invalide negestionate. La dezinstalare, APNs returnează
BadDeviceToken, FCM returneazăUNREGISTERED. Dacă nu procesezi aceste răspunsuri, trimiți în gol și nu ai date reale de delivery rate. Adaugă un job periodic care șterge token-urile invalide. - Payload peste 4 KB. Ambele platforme resping payload-ul care depășește limita la nivel de API, fără livrare și fără fallback. Payload-ul conține identificatori și text scurt; datele detaliate se încarcă la deschiderea notificării.
- Silent push ca livrare garantată. iOS poate respinge silent push dacă bateria e scăzută sau pragul de trei pe oră a fost atins. Logica critică de sincronizare are nevoie de un mecanism de recuperare la deschiderea activă.
- Badge count nesincronizat. Badge-ul se setează din payload, nu se resetează automat la citire. Resetarea cere un apel explicit la APNs/FCM cu valoarea zero; fără ea, badge-ul rămâne greșit pe device-urile pe care utilizatorul nu a deschis notificarea.
- Retry fără TTL explicit. Un mesaj trimis cu TTL implicit poate fi livrat ore mai târziu, când contextul nu mai e relevant. O promoție valabilă 6 ore livrată după 12 ore creează confuzie și eventual opt-out. Setează TTL explicit proporțional cu urgența mesajului.
- Thundering herd la deschidere. Când trimiți push la un segment mare, toți utilizatorii pot deschide aplicația în același interval și genera cereri simultane. Practici de rate limiting și circuit breaker se aplică și aici.
Dacă aplici OTA updates, coordonează versiunile de payload cu versiunile de aplicație: un payload nou trimis unei versiuni vechi poate eșua silențios. Leagă actualizările de payload de ciclul de deep linking.
Întrebări frecvente
Care e diferența dintre APNs și FCM?
APNs este infrastructura Apple pentru notificări pe iOS/macOS, iar FCM este serviciul Google care abstractizează APNs, propriul transport Android și WebPush într-un singur API. Dacă construiești o aplicație nativă iOS, livrarea finală trece mereu prin APNs, chiar dacă trimiți mesajul prin FCM. FCM normalizează payload-ul și gestionează retry-ul, APNs face livrarea efectivă pe device.
De ce iOS cere permisiune explicită, dar Android 12 nu?
Apple a introdus opt-in explicit din iOS 8 (2014); Google a urmat abia în Android 13 (2022). Pe Android 12 și mai vechi, notificările sunt activate implicit la instalare, ceea ce explică opt-in rates mai mari pe ecosistemul Android mai vechi. Din Android 13, comportamentul este aliniat cu iOS: utilizatorul trebuie să aprobe explicit.
Ce înseamnă silent push și de ce e limitat?
Un silent push este o notificare fără alertă vizibilă, folosită să trezească aplicația în fundal pentru o actualizare de date. APNs limitează silent push-urile la trei livrări pe oră per device, pentru a proteja bateria. Depășirea pragului face ca payload-ul să fie respins sau ignorat. FCM are mecanismul echivalent prin mesaje cu prioritate mică (data messages).
Cum evit că utilizatorii dezactivează notificările?
Prin frequency cap și segmentare pe tipuri de mesaj. Notificările de tip transactional (comandă plasată, status livrare) au toleranță ridicată; cele de marketing au toleranță scăzută. Un utilizator care primește cinci notificări promoționale pe zi dezactivează permisiunea în medie după câteva zile. Separă cele două canale și aplică un cap explicit pe notificările de marketing.
Payload-ul are limite de dimensiune?
Da: APNs acceptă maximum 4 KB per notificare, iar FCM are același plafon de 4 KB pentru payload-ul de date. Depășirea limitei face ca mesajul să fie respins de server fără livrare. Payload-ul trebuie să conțină identificatori și instrucțiuni minime; datele efective se încarcă din backend la deschiderea notificării.