18 dic 2025·7 min di lettura

APNs vs FCM per le notifiche push iOS e Android

Confronto APNs vs FCM per iOS e Android: ciclo di vita dei token, limiti payload, aspettative di consegna e checklist pratica per risolvere notifiche mancanti.

APNs vs FCM per le notifiche push iOS e Android

Cosa stai confrontando (e perché conta)

APNs (Apple Push Notification service) e FCM (Firebase Cloud Messaging) sono i canali che spostano un messaggio dal tuo server al telefono. Non decidono cosa fa la tua app con il messaggio, ma influenzano fortemente se il messaggio arriva, quanto velocemente arriva e in che forma deve essere.

Quando si dice che una notifica push “funziona su Android ma non su iOS” (o viceversa), raramente è un singolo bug. iOS e Android gestiscono il lavoro in background, il risparmio energetico, i permessi e la priorità dei messaggi in modo diverso. Lo stesso messaggio può essere ritardato, sostituito da uno più recente, mostrato senza suono o mai visualizzato se l'app non può svegliarsi per elaborarlo.

Questo confronto si concentra sulle parti che causano le sorprese più reali: come i token dei dispositivi cambiano nel tempo, quanto grande può essere il payload e come deve essere strutturato, quale consegna puoi realisticamente aspettarti e le ragioni comuni per cui le notifiche sembrano mancare.

Questo non copre la scelta di un’interfaccia per il provider di push, strategie di marketing o la costruzione di una pipeline completa di analytics. L'obiettivo qui è affidabilità e debug più veloce.

Alcuni termini usati in questo articolo:

  • Token: un indirizzo specifico del dispositivo a cui invii, emesso da APNs o FCM.
  • Topic: un indirizzo di gruppo (usato principalmente con FCM) dove si possono iscrivere molti dispositivi.
  • Channel: una categoria di notifica Android che controlla suono, importanza e comportamento.
  • Collapse key: un modo per sostituire messaggi in attesa più vecchi con uno nuovo.
  • TTL (time to live): quanto a lungo un messaggio può aspettare la consegna prima di scadere.

Avere questi concetti corretti risparmia ore di indagini quando una “semplice push” si comporta diversamente su iOS e Android.

Come funzionano APNs e FCM a grandi linee

APNs e FCM sono entrambi intermediari tra il tuo server e il telefono di un utente. La tua app non può consegnare in modo affidabile una notifica direttamente al dispositivo via internet, quindi affida questo compito ad Apple (APNs) o Google (FCM), che mantengono già connessioni affidabili con i dispositivi.

Il flusso generale è simile: la tua app ottiene un token, il tuo backend invia un messaggio al servizio push usando quel token e il servizio push lo instrada al dispositivo.

APNs in parole semplici

Su iOS, l'app si registra per le notifiche remote e (di solito) chiede il permesso all'utente. Apple fornisce quindi un device token. Il tuo backend (spesso chiamato “provider”) invia una richiesta di push a APNs che include quel token e il payload. APNs decide se può consegnare e inoltra la notifica al dispositivo.

Il tuo backend si autentica con APNs, tipicamente usando l'autenticazione basata su token (una chiave di firma). Configurazioni più vecchie usano certificati.

FCM in parole semplici

Su Android, l'istanza dell'app si registra con FCM e riceve un registration token. Il tuo backend invia un messaggio a FCM, e FCM lo instrada al dispositivo corretto. A seconda dello stato dell'app e del tipo di messaggio, FCM può mostrare automaticamente una notifica o consegnare i dati all'app per l'elaborazione.

Il tuo backend si autentica con FCM usando credenziali server (API key o service account).

Ciò che controlli: il codice dell'app, quando chiedi il permesso, lo storage dei token, la logica del backend e il payload che invii. Ciò che controllano Apple e Google: la rete di consegna, la raggiungibilità, le regole di throttling e molte condizioni dell'ultimo miglio come risparmio energetico e politiche di sistema.

Ciclo di vita del token: come vengono emessi, rinfrescati e invalidati i token

La differenza più importante nel giorno per giorno tra APNs e FCM è che i token non sono “impostati una volta per sempre”. Trattali come indirizzi che possono cambiare senza preavviso.

Su iOS, il device token APNs è legato al dispositivo, alla tua app e alla tua configurazione Apple developer. Può cambiare dopo una reinstallazione dell'app, un ripristino del dispositivo, alcuni aggiornamenti di sistema o quando si cambia l'ambiente push (sandbox vs production) durante lo sviluppo.

Su Android, il registration token FCM può aggiornarsi quando l'app viene ripristinata su un nuovo dispositivo, l'utente cancella i dati dell'app, Google ruota il token o l'app viene reinstallata. La tua app dovrebbe aspettarsi eventi di refresh e inviare il nuovo token al server prontamente.

Una regola semplice: esegui sempre upsert dei token, mai “inserire e dimenticare”. Quando memorizzi i token, conserva abbastanza contesto per evitare duplicati e destinazioni sbagliate:

  • ID utente o account (se applicabile)
  • Bundle/package dell'app e ambiente
  • Piattaforma (iOS/Android)
  • Valore del token e timestamp dell'ultima ricezione
  • Stato di opt-in (permesso accordato/negato)

Le cancellazioni contano anche. Di solito scopri che un token è morto dagli errori di consegna, non da un segnale pulito di “disinstallazione”. Se APNs restituisce un errore come Unregistered (spesso con status 410), o FCM risponde NotRegistered/Unregistered, rimuovi immediatamente quel token così smetti di riprovare all'infinito.

Un modo facile per perdere aggiornamenti privati: un cliente esegue il logout e un altro effettua il login sullo stesso telefono. Se non cancelli o rimappi il token al logout, puoi inviare notifiche alla persona sbagliata anche se la consegna “funziona”.

Vincoli di payload e differenze nella struttura del messaggio

La differenza pratica più grande tra APNs e FCM è quanto puoi inserire in un messaggio e come il telefono lo tratta quando arriva.

La maggior parte dei team si affida a un piccolo insieme di campi:

  • Titolo e testo del corpo
  • Conteggio badge (iOS)
  • Suono (di default o custom)
  • Dati personalizzati key-value (per esempio, order_id, status)

Limiti di dimensione: tieni la push piccola

Entrambi i servizi hanno limiti di dimensione del payload, e il limite include i tuoi dati personalizzati. Quando raggiungi il limite, la consegna può fallire o il messaggio potrebbe non comportarsi come ti aspetti.

Un pattern affidabile è inviare una notifica breve più un ID, poi recuperare i dettagli dal backend:

Esempio: invece di inviare un riepilogo ordine completo, invia { "type": "order_update", "order_id": "123" } e lascia che l'app chiami la tua API per caricare l'ultimo stato.

Comportamento data-only vs notifica

Su Android, un messaggio FCM con payload “notification” viene tipicamente mostrato dal sistema quando l'app è in background. Un messaggio solo-dati viene consegnato al codice dell'app, ma può essere ritardato o bloccato dalle limitazioni in background e dalle impostazioni di risparmio batteria.

Su iOS, gli alert (titolo/corpo) sono semplici, ma gli aggiornamenti in background sono più restrittivi. Una push in background non garantisce che il tuo codice venga eseguito immediatamente. Trattala come un suggerimento per aggiornare, non come un trigger in tempo reale.

Se ti serve affidabilità, mantieni il payload minimo, includi un identificatore stabile e progetta l'app per riconciliare lo stato quando si apre o riprende.

Cosa aspettarsi dalla consegna e cosa può fermare una notifica

Prototipa notifiche in poche ore
Testa payload minimi e iterare rapidamente senza riscrivere il backend.
Prototype Now

Con APNs e FCM, la consegna è best-effort. Il provider cercherà di consegnare il tuo messaggio, ma non garantisce che il dispositivo lo mostrerà.

La raggiungibilità è il primo limite. Invi un messaggio con TTL o expiry. Se il dispositivo torna online dopo quella finestra, la push viene scartata. Se il TTL è molto lungo, l'utente potrebbe vedere un alert vecchio più tardi, che sembra un bug.

La priorità influisce sui tempi, ma non è un upgrade gratuito. L'alta priorità può aiutare i messaggi urgenti ad arrivare prima, specialmente quando il dispositivo è addormentato. L'abuso può portare a throttling, consumo batteria o a far sì che il sistema tratti la tua app da rumorosa.

Entrambi i sistemi supportano il collapsing così un messaggio più nuovo sostituisce uno più vecchio invece di accumularsi. APNs usa un collapse identifier, FCM usa una collapse key. Se fai collapse su qualcosa come order_status, l'utente potrebbe vedere solo l'ultimo stato, non ogni passaggio.

Anche quando il provider consegna con successo, il telefono può comunque impedire all'utente di vederla:

  • Do Not Disturb o modalità Focus possono silenziare o nascondere gli avvisi
  • Le impostazioni di notifica dell'app possono essere disabilitate o impostate su consegna silenziosa
  • I canali di notifica Android possono essere disattivati per una categoria specifica
  • Le restrizioni di background o i risparmi batteria possono ritardare la consegna
  • Il sistema operativo può sopprimere ripetizioni se la tua app pubblica molti avvisi simili

Tratta la push come un trasporto non affidabile: conserva lo stato importante nel backend e fai sì che l'app aggiorni lo stato quando viene aperta, anche se una notifica non è mai mostrata.

Permessi e impostazioni del dispositivo che influenzano la consegna

Molti problemi di “consegna” sono in realtà problemi di permessi e impostazioni.

Su iOS, il primo prompt dei permessi conta. Se l'utente tocca “Non consentire”, le notifiche non appariranno fino a quando non lo cambia nelle Impostazioni. Anche dopo l'autorizzazione, può disattivare Schermata di blocco, Centro notifiche, banner, suoni o badge. Le modalità Focus e lo Scheduled Summary possono anche nascondere o ritardare gli avvisi.

Su Android, i requisiti dipendono dalla versione di OS. Le versioni più recenti richiedono un permesso runtime per le notifiche, quindi un aggiornamento dell'app può improvvisamente fermare la visualizzazione delle notifiche fino a quando l'utente non approva di nuovo. La visibilità dipende anche dai canali di notifica. Se il canale è silenziato o impostato a bassa importanza, le push possono arrivare ma non interrompere l'utente.

Le restrizioni in background possono rompere le aspettative. Low Power Mode su iOS e ottimizzazioni batteria su Android possono ritardare il lavoro in background, bloccare i dati in background o impedire all'app di processare un messaggio solo-dati.

Per confermare cosa sta succedendo, registra ciò che il dispositivo vede, non solo quello che il backend ha inviato:

  • Log in-app: “permesso concesso”, “token registrato”, “notifica ricevuta”, “notifica mostrata”
  • Indicatori OS: stato delle impostazioni notifiche (abilitate/silenziate/importanza canale) e modalità batteria
  • Callback di push: se la tua app ha ricevuto il messaggio in foreground/background

Anche se il tuo backend è costruito con uno strumento no-code, il logging client-side è ciò che separa “messaggio non ricevuto” da “ricevuto ma sopresso”.

Passo dopo passo: come risolvere le notifiche mancanti

Aggiungi un fallback in-app affidabile
Crea una inbox in-app in modo che gli utenti vedano comunque gli aggiornamenti quando le notifiche vengono perse.
Get Started

Quando una push manca, trattala come una catena: token, provider, payload e comportamento dell'app. I sintomi possono sembrare gli stessi su iOS e Android, quindi controlla sempre gli stessi punti in ordine.

  • Conferma che stai inviando a un token attuale. Confronta il token sul server con quello che l'app ha riportato più recentemente. Registra quando hai ricevuto l'ultimo token.
  • Valida il payload prima di inviarlo. Tienilo sotto i limiti della piattaforma, usa i campi richiesti ed evita JSON malformato. Se invii messaggi solo-dati, conferma che l'app è costruita per gestirli.
  • Controlla credenziali e ambiente del provider. Per APNs, conferma key/cert, team, bundle ID e se stai targettando sandbox vs production. Per FCM, conferma le credenziali del progetto corretto.

Poi restringi se è il contenuto del messaggio o il comportamento del dispositivo/app:

  • Invia una notifica di test minima. Un payload piccolo con titolo/body aiuta a confermare che il trasporto funziona.
  • Verifica gli handler lato app e il comportamento in foreground. Molte “push mancanti” sono ricevute ma non mostrate. Alcune app sopprimono i banner in foreground per scelta.
  • Cambia una variabile alla volta. Prova un secondo dispositivo, una versione OS diversa, Wi-Fi vs cellulare e un account utente differente. Se fallisce solo un account, spesso è colpa di token obsoleti o targeting server-side.

Un pattern pratico: se utenti iOS segnalano mancanze ma Android è OK, inizia inviando un alert minimo su iOS. Se funziona, concentrati sulla struttura del payload e sull'handling dell'app. Se non funziona, concentra l'attenzione su token e credenziali/ambiente APNs.

Errori comuni che causano fallimenti silenziosi

Rendi il targeting meno soggetto a errori
Sposta regole di targeting e stato di opt-in in un modello dati pulito per ridurre gli errori.
Try No Code

La maggior parte dei problemi push non è dovuta a outage. Sono piccole discrepanze tra ciò che la tua app si aspetta e ciò che APNs o FCM accetteranno, o ciò che il telefono permetterà.

L'errore più comune è inviare a un token non più valido. I token cambiano dopo reinstall, ripristino o refresh. Se il tuo server continua a usare il valore vecchio, le push non vanno da nessuna parte.

Un altro è trattare la consegna push come garantita. La consegna best-effort significa che messaggi in ritardo o mancanti sono normali quando i dispositivi sono offline o sotto regole di risparmio energetico. Per eventi importanti (aggiornamenti ordine, avvisi di sicurezza) serve un fallback in-app come il recupero dello stato all'apertura.

Cause comuni di notifiche mancanti:

  • Token iOS o Android obsoleti mantenuti dopo reinstall/refresh
  • Superamento dei limiti di payload (troppi dati personalizzati, immagini sovradimensionate, stringhe lunghe)
  • Affidarsi alla consegna in background per aggiornamenti silenziosi, quindi essere soggetti a throttling dal SO
  • Mescolare ambienti iOS (development vs production), quindi token ed endpoint APNs non corrispondono
  • Ignorare opt-out utente, Focus/Do Not Disturb, canali di notifica disattivati (Android) o permessi app disabilitati

Esempio: un'app retail invia un alert “ordine spedito” con un grande blob JSON di cronologia tracciamento. La chiamata di invio sembra corretta, ma il payload viene rifiutato o troncato e l'utente non vede nulla. Tieni la push leggera e metti i dettagli dietro una chiamata API.

Checklist rapida prima di incolpare APNs o FCM

Prima di presumere che il provider sia il problema, esegui un controllo di sanità:

  • Conferma che il token è corretto per l'utente e il dispositivo. Deve esistere, essere aggiornato di recente e mappato alla sessione giusta.
  • Verifica che le credenziali del provider siano valide ora. Controlla key/cert APNs e che le credenziali FCM corrispondano alla app/progetto giusto.
  • Valida forma e dimensione del payload. Rimani sotto i limiti e usa i campi corretti.
  • Imposta TTL, priorità e collapse in modo intenzionale. Un TTL basso può scadere prima che il telefono torni online. Una priorità bassa può ritardare la consegna. Il collapse può sostituire messaggi precedenti.
  • Separa “server accettato” da “device mostrato”. Confronta i log server (request/response/message ID) con i log client (token usato, handler chiamato).

Poi fai un controllo veloce sul dispositivo: notifiche consentite per l'app, canale/categoria configurato correttamente (i canali Android sono un classico problema), Focus/Non disturbare, e restrizioni background.

Esempio: diagnosticare una notifica di aggiornamento ordine mancante

Genera app native per entrambi
Distribuisci app native iOS e Android che funzionano con APNs e FCM nel modo corretto.
Build Mobile Apps

Un operatore di supporto tocca “Invia aggiornamento ordine” per l'Ordine #1842. I log del backend mostrano “notifica inviata”, ma il cliente non vede nulla né sul suo iPhone né sul suo telefono Android.

Inizia dal backend. La maggior parte delle notifiche “mancanti” o non viene accettata dal servizio push, o viene accettata ma scartata più tardi perché il dispositivo non può (o non vuole) mostrarla.

Controlli backend prima di tutto

Cerca un singolo tentativo tracciabile di invio (un aggiornamento ordine dovrebbe generare una richiesta push). Poi verifica:

  • Il token usato è il più recente memorizzato per quell'utente e dispositivo.
  • La risposta del provider è un successo e hai salvato eventuali codici di errore.
  • Il payload rispetta le regole della piattaforma (limiti dimensione, campi richiesti, JSON valido).
  • L'autenticazione è valida (chiave/cert APNs e team/bundle ID, o credenziali FCM).
  • Hai targettato l'ambiente iOS corretto (sandbox vs production).

Se i log mostrano un rifiuto come “unregistered/invalid token”, è un problema di ciclo di vita del token. Se il provider accetta il messaggio ma niente arriva, concentrati sul tipo di payload e sul comportamento del SO.

Controlli sul telefono

Ora valida che il telefono sia autorizzato a mostrare l'alert:

  • Le notifiche sono abilitate per l'app (e consentite per Schermata di blocco/Banner).
  • Focus/Do Not Disturb o i riepiloghi non lo stanno nascondendo.
  • Le modalità di risparmio batteria non stanno limitando il lavoro in background (più comune su Android).
  • Lo stato dell'app corrisponde al tipo di messaggio (la gestione in foreground può inghiottire gli avvisi).

Un esito comune: il token è a posto, ma il messaggio è solo-dati (Android) o manca la corretta configurazione iOS per l'handling in background, quindi il SO non mostra l'alert. La soluzione è inviare il tipo di payload giusto per l'obiettivo (alert visibile vs aggiornamento in background) e mantenere log puliti di aggiornamenti token e risposte del provider.

Prossimi passi: rendere la push più affidabile nel tuo prodotto

Le notifiche push sembrano semplici finché non diventano una funzionalità centrale. L'affidabilità viene dai pezzi che controlli: igiene dei token, disciplina del payload e un percorso di fallback.

Pianifica i casi di mancata consegna. La push è ottima per i momenti “guarda ora”, ma non dovrebbe essere l'unica via per eventi critici. Una inbox in-app aiuta gli utenti a recuperare gli aggiornamenti, ed email o SMS possono coprire azioni ad alto valore come reset password o problemi di pagamento.

Mantieni il payload snello. Tratta il payload push come un prompt, non come il messaggio completo. Invia un tipo di evento e un ID, poi recupera i dettagli dalla tua API quando l'app si apre o riceve un appropriato aggiornamento in background.

Scrivi un breve runbook per il tuo team così il debug rimane coerente: stato opt-in, freschezza dei token, codici di risposta del provider, dimensione/forma del payload e ambiente/credenziali.

Se stai costruendo con AppMaster (appmaster.io), può essere comodo mantenere storage token, audit log e logica di trigger delle push insieme in un backend, pur distribuendo app native iOS e Android che gestiscono correttamente APNs e FCM.

FAQ

What’s the simplest way to explain APNs vs FCM?

APNs è il servizio di consegna di Apple per le notifiche push su iOS, mentre FCM è il servizio di Google per Android (e può anche raggiungere iOS tramite APNs). La tua app decide ancora cosa fare con il messaggio, ma questi servizi determinano come ti autentichi, come formattare i payload e quale comportamento di consegna aspettarti.

Do device tokens stay the same forever?

Tratta i token come indirizzi che possono cambiare. Salvali con informazioni su piattaforma e ambiente, aggiornali ogni volta che l'app segnala un nuovo valore e rimuovili quando il provider ti dice che sono invalidi. La regola pratica è eseguire l'upsert dei token e mantenere un timestamp “last seen” così puoi individuare record obsoleti rapidamente.

What usually causes an iOS or Android push token to change?

Su iOS i token cambiano spesso dopo una reinstallazione, un ripristino del dispositivo, alcuni aggiornamenti di sistema o quando si passa tra sandbox e produzione durante lo sviluppo. Su Android, i token FCM possono aggiornarsi dopo reinstall, cancellazione dei dati dell'app, ripristino del dispositivo o quando Google ruota i token. L'app dovrebbe ascoltare gli eventi di refresh e inviare subito il nuovo token al backend.

How should I structure a push payload to avoid problems?

Mantieni il payload della push piccolo e trattalo come un prompt. Invia un breve titolo/body (se serve un alert visibile) più un identificatore stabile come order_id, poi lascia che l'app recuperi i dettagli completi dalla tua API. Questo evita limiti di payload, riduce casi estremi strani e rende il comportamento più coerente tra le piattaforme.

What’s the difference between “notification” and “data-only” messages?

Un payload di notifica è pensato per essere mostrato all'utente, mentre un payload solo-dati è pensato per essere elaborato dall'app. Su Android i messaggi solo-dati possono essere ritardati o bloccati dalle limitazioni in background e dalle impostazioni di risparmio batteria, quindi non sono un trigger affidabile per lavoro immediato. Su iOS, le push in background non garantiscono l'esecuzione immediata del codice, perciò vanno considerate un suggerimento per aggiornare lo stato, non come esecutore di job in tempo reale.

Are push notifications guaranteed to be delivered and shown?

No: la consegna è best-effort. Anche se APNs o FCM accettano la tua richiesta, il dispositivo può essere offline, il messaggio può scadere per TTL, il sistema operativo può limitare la consegna o le impostazioni dell'utente possono sopprimere gli avvisi. Progetta l'app in modo che lo stato critico sia sempre corretto quando l'utente la apre, anche se la notifica non viene mai mostrata.

What’s the fastest way to debug a missing notification?

Inizia separando “inviato” da “visualizzato”. Conferma che il token è attuale, invia un payload di prova minimo con titolo/body, e verifica di usare le credenziali APNs/FCM corrette e (per iOS) l'ambiente giusto. Se il provider accetta il messaggio, controlla le impostazioni del telefono come Focus/Non disturbare, permessi notifiche dell'app e canali di notifica Android, perché la notifica potrebbe essere ricevuta ma soppressa.

Why do notifications work on Android but not on iOS (or the opposite)?

Su iOS molte volte i problemi derivano dalla negazione dei permessi, dalle modalità Focus o dal targeting dell'ambiente APNs sbagliato (sandbox vs production). Su Android, i blocchi comuni sono il permesso runtime per le notifiche sulle versioni più recenti, canali di notifica disattivati o a bassa importanza, e ottimizzazioni energetiche aggressive che ritardano l'elaborazione in background. Lo stesso invio dal backend può risultare valido mentre il dispositivo impedisce silenziosamente la visualizzazione.

How do TTL and “collapse key” affect what users see?

TTL controlla per quanto tempo il provider deve continuare a provare mentre il dispositivo è offline, e le impostazioni di collapse decidono se i messaggi più nuovi sostituiscono quelli più vecchi in coda. Un TTL breve può far sparire le notifiche se il telefono è offline a lungo, e collapse key/identifier possono fare vedere solo l'ultimo aggiornamento. Imposta questi valori deliberatamente in base all'esperienza utente desiderata.

How can AppMaster help me build a reliable push notification setup?

Mantieni lo storage dei token, le regole di targeting e i log di invio insieme così puoi tracciare ogni tentativo di push end-to-end. AppMaster (appmaster.io) può aiutare centralizzando tabelle di token, audit log e la logica di invio nel backend, mentre le tue app native iOS e Android gestiscono correttamente APNs e FCM. L'essenziale è registrare gli aggiornamenti dei token, le risposte del provider e le ricezioni client-side per capire se il problema è server, provider o dispositivo.

Facile da avviare
Creare qualcosa di straordinario

Sperimenta con AppMaster con un piano gratuito.
Quando sarai pronto potrai scegliere l'abbonamento appropriato.

Iniziare