Salta al contenuto principale
Mobile Guide

Guida completa alle Expo Push Notification 2026

Configura al meglio le notifiche push di Expo. Questa guida copre permessi, token, invio, gestione e best practice per una consegna affidabile in produzione.

Guida completa alle Expo Push Notification 2026

Probabilmente sei arrivato al punto in cui l'app funziona, gli utenti hanno effettuato l'accesso e il business vuole flussi di re-engagement che sembrino nativi. Promemoria del carrello. Prompt per le recensioni. Alert per nuovi messaggi. Annunci di rilascio. L'istinto iniziale è spesso quello di "collegare le push e via", ma una settimana dopo ti ritrovi a fare debugging sul perché un dispositivo riceve gli alert, il simulatore sembra registrare tutto correttamente e nessuno sa spiegare perché i tap non aprono la schermata giusta.

È qui che le notifiche push di Expo possono essere piacevolmente semplici o sorprendentemente fragili.

Expo offre ai team React Native uno strato pratico sopra APNs e FCM, ed è proprio per questo che viene usato da così tanti team. Tuttavia, il divario tra una demo e un'implementazione pronta per la produzione è reale. Il ciclo di vita dei token, il timing dei permessi, la configurazione dei listener, il design del payload e la pulizia del backend sono tutti fattori cruciali. Se rilasci anche frequenti modifiche alla logica dell'app, la necessità di disciplina operativa diventa ancora più stringente, specialmente se il tuo lavoro di retention dipende da messaggistica affidabile e velocità di rilascio. La consegna è utile solo se l'esperienza utente che la circonda è prevedibile.

Indice dei contenuti

Le basi per coinvolgere gli utenti con le Expo Push Notifications

Un Notifiche push di Expo Il setup è interessante soprattutto per un motivo: elimina gran parte della complessità della messaggistica nativa che i team non vogliono gestire fin dal primo giorno. Invece di costruire subito l'infrastruttura APNs e FCM, puoi usare il gateway di Expo e concentrarti sul comportamento del prodotto, sul routing, sulla UX dei permessi e sulla logica dei messaggi lato backend.

Quell'astrazione non rende le notifiche push "meno reali". Cambia solo dove concentrare i tuoi sforzi di ingegneria.

Il servizio è anche abbastanza veloce: di solito le performance non sono la prima cosa di cui preoccuparsi. Dal 14 marzo 2023 al 12 giugno 2023, il API delle notifiche push di Expo ha mostrato un tempo di risposta mediano di 42 millisecondi, una latenza p99 di 273 millisecondi, e un tasso di errore giornaliero medio dello 0,17% su decine di milioni di messaggi giornalieri, secondo i dati di l'analisi benchmark di Knock su API push di Expo. Questo dovrebbe rassicurare i team che si chiedono se Expo sia adatto solo ai prototipi.

Cosa astrae davvero Expo

Quando i team parlano di “Expo push”, spesso intendono diversi aspetti distinti raggruppati insieme:

  • Routing del provider: Expo inoltra i messaggi a APNs per iOS e FCM per Android.
  • Formato del token: Il tuo server salva e invia un Expo Push Token invece di gestire prima i token specifici della piattaforma.
  • Contratto della richiesta: Invece di integrare direttamente le API dei provider nativi, invii un payload tramite l'API di Expo via POST.

È un vantaggio, ma crea anche un malinteso comune. Spesso i team pensano che ogni problema di consegna dipenda da Expo. In realtà, molti errori derivano da code dell'app, token scaduti, payload malformati o una gestione errata dei permessi.

Regola pratica: Considera Expo come un affidabile layer di trasporto, non come un sostituto di un buon design client e backend.

Cosa significa davvero essere pronti per la produzione

Una demo funzionante dimostra solo che un dispositivo ha ricevuto un payload una volta. Essere pronti per la produzione significa altro:

Aspetto Approccio Demo Approccio Production
Permessi Chiedi subito Chiedi nel contesto, dopo aver creato valore
Token Save once Refresh, deduplicazione, scadenza e riconciliazione
Payload Inserisci tutto data Mantieni i payload piccoli e orientati all'azione
Comportamento dell'app Mostra un alert Navigazione corretta e gestione dello stato in foreground
Operazioni Test manuali Ricevute, cleanup, log e gestione incidenti

Questa è la differenza tra "inviare notifiche" e "gestire le notifiche in un vero workflow di prodotto".

Configurazione e setup iniziale del progetto

Molti problemi con le notifiche Expo iniziano prima del primo prompt di autorizzazione. Se la configurazione del progetto è approssimativa, il client code può sembrare corretto, mentre l'app si comporta in modo inconsistente tra i vari build.

Un laptop moderno su una scrivania di legno che mostra i file di configurazione code per il setup di un progetto.

Inizia con le librerie giuste installate e un ambiente di sviluppo che rispecchi il tuo percorso di build. Se lavori oltre Expo Go, è utile allineare il tuo workflow di rilascio con Guida all'alternativa di Capgo a Expo EAS, perché il comportamento delle notifiche deve spesso essere validato in un build che rispecchi la produzione più fedelmente rispetto a un rapido test in sandbox.

Installa i pacchetti per le notifiche

Al minimo, di solito avrai bisogno di:

  • expo-notifications per richieste di permessi, recupero token, listener e visualizzazione delle notifiche.
  • expo-device perché dovresti proteggere il recupero del token con Device.isDevice.

I comandi di installazione tipici dipendono dal tuo package manager, ma la chiave è l'allineamento delle versioni con il tuo SDK di Expo. Non mischiare versioni arbitrarie dei pacchetti. Lascia che Expo risolva quelle compatibili.

Aggiungi la configurazione a livello di progetto

Mantieni la configurazione esplicita. Un app.json o app.config.js dovrebbe riflettere il fatto che le notifiche sono parte del contratto della tua app, non un'aggiunta postuma.

{
  "expo": {
    "name": "MyApp",
    "slug": "my-app",
    "plugins": ["expo-notifications"],
    "ios": {
      "bundleIdentifier": "com.example.myapp"
    },
    "android": {
      "package": "com.example.myapp"
    },
    "extra": {
      "eas": {
        "projectId": "your-project-id"
      }
    }
  }
}

Alcuni dettagli sono importanti qui:

  • Bundle identifier e nomi dei pacchetti devono corrispondere all'app che effettivamente pubblichi.
  • Il plugin delle notifiche garantisce la configurazione nativa necessaria durante il build.
  • L'EAS project ID è fondamentale quando il recupero del token richiede l'associazione dell'app al corretto progetto Expo.

Imposta un handler per le notifiche subito

Molti tutorial di base aspettano troppo a definire il comportamento delle notifiche. Non farlo: impostalo vicino all'avvio dell'app, così il comportamento in foreground è prevedibile.

import * as Notifications from 'expo-notifications';

Notifications.setNotificationHandler({
  handleNotification: async () => ({
    shouldShowAlert: true,
    shouldPlaySound: false,
    shouldSetBadge: true,
  }),
});

I team decidono se le notifiche in foreground debbano mostrare un alert, riprodurre un suono o aggiornare i badge. Il comportamento esatto dipende dal tuo prodotto: un'app di chat e una di pagamenti faranno scelte diverse.

Se non definisci intenzionalmente il comportamento in foreground, il team finirà per debuggare notifiche "mancanti" che in realtà sono state ricevute, ma non presentate come previsto dal prodotto.

Android richiede la configurazione dei canali

In pratica, i canali di notifica Android non sono opzionali. Se li ignori, i tuoi avvisi potrebbero apparire incoerenti o non rispettare le aspettative dell'utente.

import { Platform } from 'react-native';
import * as Notifications from 'expo-notifications';

export async function configureAndroidNotifications() {
  if (Platform.OS !== 'android') return;

  await Notifications.setNotificationChannelAsync('default', {
    name: 'Default',
    importance: Notifications.AndroidImportance.MAX,
  });
}

Configura tutto durante l'inizializzazione dell'app. Poi mantieni stabili gli ID dei canali: cambiarli senza motivo rende il comportamento delle notifiche più difficile da gestire in seguito.

Richiedere i permessi e catturare i push token

Questa è la parte che molti team copiano da uno snippet, per poi pentirsene.

Le richieste di permesso richiedono il timing giusto, consapevolezza della piattaforma e una gestione async rigorosa. La cattura del token deve avvenire solo su un dispositivo fisico, solo dopo che i permessi sono stati risolti e solo se sei pronto a salvare subito il risultato sul tuo backend.

Un diagramma passo-passo che mostra il processo per ottenere e salvare i token delle notifiche push di Expo.

La funzione client da usare come baseline

Parti da una funzione come questa:

import * as Device from 'expo-device';
import * as Notifications from 'expo-notifications';
import Constants from 'expo-constants';
import { Platform } from 'react-native';

type RegisterResult =
  | { ok: true; token: string }
  | { ok: false; reason: string };

export async function registerForExpoPushNotificationsAsync(): Promise<RegisterResult> {
  if (!Device.isDevice) {
    return { ok: false, reason: 'Push notifications require a physical device.' };
  }

  if (Platform.OS === 'android') {
    await Notifications.setNotificationChannelAsync('default', {
      name: 'Default',
      importance: Notifications.AndroidImportance.MAX,
    });
  }

  const permissions = await Notifications.getPermissionsAsync();
  let finalStatus = permissions.status;

  if (finalStatus !== 'granted') {
    const request = await Notifications.requestPermissionsAsync();
    finalStatus = request.status;
  }

  if (finalStatus !== 'granted') {
    return { ok: false, reason: 'Notification permission was not granted.' };
  }

  const projectId =
    Constants.expoConfig?.extra?.eas?.projectId ??
    Constants.easConfig?.projectId;

  if (!projectId) {
    return { ok: false, reason: 'Missing EAS project ID configuration.' };
  }

  const tokenResponse = await Notifications.getExpoPushTokenAsync({ projectId });

  return { ok: true, token: tokenResponse.data };
}

L'ordine è fondamentale. Prima controlli il tipo di dispositivo, imposti il comportamento del canale Android, risolvi i permessi, validi la configurazione del progetto e infine richiedi il token Expo.

Perché Device.isDevice non è opzionale

Questo è uno dei pochi errori che genera molto rumore pur sembrando innocuo. I team esperti richiedono i permessi solo condizionalmente quando Device.isDevice è true, ed un errore comune è saltare questo controllo, portando gli sviluppatori a inviare notifiche a token di simulatori non validi e a incolpare Expo, quando il problema è la configurazione dell'app, come descritto in Note sull'implementazione delle notifiche Expo di Eagerworks.

Ecco perché il controllo va messo all'inizio della funzione. Non nasconderlo in una helper. Rendilo esplicito.

I risultati del simulatore sono utili per i test della UI, ma non sono affidabili per validare la registrazione del push token.

Chiedi il permesso al momento giusto

Non chiedere il permesso nella splash screen. Non chiederlo prima che l'utente ne capisca il valore. Il momento migliore è di solito dopo un'azione che rende concreti i vantaggi delle notifiche, come attivare gli aggiornamenti di consegna, entrare in una conversazione o salvare un elemento nella watchlist.

Una buona implementazione segue di solito questo flusso:

  1. L'utente raggiunge un punto chiave della funzionalità.
  2. L'app spiega il valore delle notifiche nella propria UI.
  3. L'app richiede il permesso di sistema.
  4. Se il permesso è concesso, l'app salva subito il token sul backend.

È proprio in quest'ultimo passaggio che molte app falliscono. Recuperano il token, lo loggano localmente e rimandano la registrazione al backend. In seguito, il supporto non sarà in grado di dire quale dispositivo avesse quale token in un dato momento.

Ecco un semplice esempio di come salvare il token dopo la registrazione:

export async function enablePushForCurrentUser(userId: string) {
  const result = await registerForExpoPushNotificationsAsync();

  if (!result.ok) {
    return result;
  }

  await fetch('https://api.example.com/push-tokens', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: 'Bearer user-session-token',
    },
    body: JSON.stringify({
      userId,
      token: result.token,
      platform: Platform.OS,
    }),
  });

  return result;
}

Più avanti nel workflow, questa guida è un utile riferimento visivo:

Per i team che sviluppano app con rilasci frequenti, è anche utile considerare la registrazione del token come parte dello stato operativo dell'app, non solo dell'onboarding. Questo approccio si sposa bene con i più ampi workflow di distribuzione delle app Expo, dove il comportamento dell'app può cambiare spesso e lo stato del backend deve restare sincronizzato.

Inviare notifiche dal tuo server

Una volta che il tuo backend ha un Expo Push Token valido, inviare una notifica è semplice. La parte difficile non è la richiesta in sé: è decidere cosa includere nel payload e quanta fiducia riporre nello stato del client.

Ecco un esempio minimale in stile Node che usa fetch:

type ExpoPushMessage = {
  to: string;
  title: string;
  body: string;
  sound?: 'default' | null;
  data?: Record<string, unknown>;
};

export async function sendExpoPushNotification(token: string) {
  const message: ExpoPushMessage = {
    to: token,
    title: 'New review received',
    body: 'Tap to open the order details.',
    sound: 'default',
    data: {
      type: 'new_review',
      orderId: 'ord_123',
      screen: 'OrderDetails',
    },
  };

  const response = await fetch('https://exp.host/--/api/v2/push/send', {
    method: 'POST',
    headers: {
      Accept: 'application/json',
      'Accept-encoding': 'gzip, deflate',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(message),
  });

  const result = await response.json();
  return result;
}

Cosa deve fare ogni campo del payload

Non usare il payload come un cestino. Ogni campo deve avere uno scopo preciso.

Campo Scopo Consigli pratici
to Expo Push Token di destinazione Verifica che appartenga al record del dispositivo corrente
title Titolo della notifica Mantienilo breve e leggibile
body Testo principale visibile Rendi l'azione chiara
sound Comportamento del suono di sistema Usalo con moderazione per avvisi critici
data Metadati specifici dell'app Preferisci ID e hint di routing ai contenuti ricchi

Il data l'oggetto è dove i workflow di prodotto diventano utili. Puoi passare un tipo e un ID del record, poi lasciare che l'app recuperi i dati più recenti quando l'utente tocca. È più sicuro rispetto a incorporare blob grandi o sensibili direttamente nel payload.

Mantieni i payload piccoli e semplici

According to la guida di Courier sulle notifiche Expo, gli Expo Push Tokens dovrebbero essere trattati come effimeri; i payload che superano limiti di dimensione di circa 4 KB possono essere scartati. Un pattern affidabile consiste nell'inviare piccoli payload di metadati come { "type": "new_review", "id": 123 } invece di grandi JSON o media inline. Questo consiglio riflette ciò che funziona nei sistemi reali. I payload piccoli falliscono meno spesso e sono più resilienti quando la logica dell'app cambia.

Invia dati sufficienti per indirizzare l'utente. Recupera il resto dopo l'apertura dell'app.

Buone pratiche lato server

Una funzione di invio base va bene per i test. In produzione, solitamente ne aggiunge altre:

  • Persistere i tentativi di invio: Salva l'intento della notifica con ID utente, token, tipo di payload e timestamp.
  • Separare la generazione dei contenuti dal trasporto: Crea il testo del messaggio in uno strato e la richiesta Expo API in un altro.
  • Gestisci il feedback di invalidazione: Se Expo segnala in seguito DeviceNotRegistered, segna quel token come scaduto e smetti di riprovare alla cieca.
  • Usa un design ottimizzato per i webhook: Se il tuo sistema emette già eventi, instrada i trigger delle notifiche attraverso lo stesso tipo di pattern di elaborazione dei webhook backend che usi altrove.

Prima di debuggare i listener lato client, invia prima un test push manuale. Se un token riceve una notifica semplice con un payload minimo, il percorso di trasporto è probabilmente funzionante. In caso contrario, non iniziare cambiando la code di navigazione. Inizia validando il token, la struttura del payload e lo stato dei permessi.

Gestire le notifiche in arrivo nella tua app

La consegna è solo metà della funzionalità. L'app deve fare qualcosa di coerente quando arriva la notifica e quando l'utente la tocca.

Ciò significa gestire due momenti distinti:

  • la notifica arriva mentre l'app è aperta
  • l'utente interagisce con la notifica dal tray di sistema o dalla schermata di blocco

Un diagramma di flusso che illustra il ciclo di vita delle notifiche push per app mobile in stato foreground e background.

Ricezione in foreground e risposta utente sono eventi diversi

Una configurazione affidabile include solitamente entrambi i listener:

import { useEffect } from 'react';
import * as Notifications from 'expo-notifications';

export function useNotificationObservers(
  onForegroundMessage: (notification: Notifications.Notification) => void,
  onNotificationTap: (response: Notifications.NotificationResponse) => void
) {
  useEffect(() => {
    const receivedSub = Notifications.addNotificationReceivedListener(
      (notification) => {
        onForegroundMessage(notification);
      }
    );

    const responseSub = Notifications.addNotificationResponseReceivedListener(
      (response) => {
        onNotificationTap(response);
      }
    );

    return () => {
      receivedSub.remove();
      responseSub.remove();
    };
  }, [onForegroundMessage, onNotificationTap]);
}

addNotificationReceivedListener viene eseguito quando l'app è attiva. addNotificationResponseReceivedListener viene eseguito quando l'utente tocca una notifica ricevuta. Non confonderli: servono a percorsi UX diversi.

Leggi il payload dei dati e naviga in modo mirato

Ecco un pattern pratico per gestire il tap:

type NotificationData = {
  type?: string;
  orderId?: string;
  screen?: string;
};

export function handleNotificationTap(
  response: Notifications.NotificationResponse,
  navigation: any
) {
  const data =
    response.notification.request.content.data as NotificationData;

  if (data.screen === 'OrderDetails' && data.orderId) {
    navigation.navigate('OrderDetails', { orderId: data.orderId });
    return;
  }

  if (data.type === 'new_review') {
    navigation.navigate('Inbox');
    return;
  }

  navigation.navigate('Home');
}

Questo pattern resta resiliente perché il payload contiene suggerimenti di routing, non interi documenti. Se l'ordine è cambiato da quando è stata inviata la notifica, l'app può recuperare lo stato attuale dal server dopo la navigazione.

Una notifica toccata deve portare a una destinazione ovvia. Se il percorso di fallback è vago, l'utente se ne accorge subito.

Foreground behavior should match user context

Quando l'app è già aperta, mostrare alla cieca un alert di sistema può risultare goffo. A volte la scelta giusta è un banner in-app, un aggiornamento del badge o un refresh silenzioso. Una schermata di inbox del supporto potrebbe non richiedere un alert visibile se l'utente sta già leggendo quella conversazione.

Ecco perché il tuo listener in foreground dovrebbe ramificare per route e tipo di notifica. Ad esempio:

  • Schermata chat aperta: aggiungi il messaggio ed evita un banner ridondante
  • Dashboard aperta: mostra un toast in-app leggero
  • Evento critico dell'account: usa un elemento UI più marcato

Un approccio semplice è questo:

export function handleForegroundNotification(
  notification: Notifications.Notification,
  currentRouteName: string
) {
  const data = notification.request.content.data as { type?: string };

  if (currentRouteName === 'ChatThread' && data.type === 'new_message') {
    // refresh local thread state
    return;
  }

  // otherwise show your own in-app UI or update badges
}

Se l'app non distingue questi contesti, gli utenti subiranno prima la notification fatigue, anche se la consegna è tecnicamente corretta.

Best practice per la produzione ed errori comuni

La maggior parte delle configurazioni Expo push notification fallisce non perché Expo sia limitato, ma perché i team assumono che il token sia permanente, che i payload possano contenere qualsiasi cosa e che gli update dell'app non influiscano sulla logica delle notifiche.

Questa ipotesi non regge in produzione.

Un'infografica con checklist che illustra otto best practice per gestire le notifiche push in produzione per le app mobile.

I token sono effimeri, non record di identità

Un Expo Push Token va trattato come un contratto a termine, non come un identificativo del dispositivo permanente. I token possono cambiare dopo una reinstallazione, aggiornamenti del sistema operativo o altri eventi del ciclo di vita. Se un token dovesse tornare DeviceNotRegistered, il tuo backend dovrebbe smettere di considerarlo attivo.

Un modello backend pratico memorizza:

  • ID utente
  • piattaforma
  • metadati relativi all'installazione
  • token corrente
  • timestamp dell'ultimo avvistamento
  • stato come active, stale o revoked

Non limitarti a salvare un singolo campo token nella tabella utenti. Gli utenti hanno più dispositivi e lo stato dei dispositivi cambia.

La strategia di refresh conta più di quanto dicano i tutorial

La guida ufficiale dell'ecosistema lascia un vuoto operativo. Spesso i contenuti sulle notifiche push di Expo non spiegano come mantenere la validità del token durante Cicli di revisione dell'App Store e aggiornamenti OTA, aspetto fondamentale per i team che rilasciano modifiche live, poiché l'affidabilità delle notifiche dipende dallo stato attuale del token e dalla sincronizzazione del backend, come indicato in Documentazione notifiche Expo.

Questo influisce sul design dei trigger di refresh. I momenti ideali per riconciliare lo stato del token includono:

  • Avvio dell'app dopo un aggiornamento
  • Accesso dell'utente
  • Modifica delle impostazioni dei permessi
  • Rotazione delle credenziali nel processo di release
  • Flussi di recovery dopo ticket di supporto sulle push

Security e compliance non vanno lasciate alla fine dello sprint

Molti tutorial su Expo si concentrano sulla meccanica e trascurano il rischio operativo. Va bene per app amatoriali, ma non per prodotti fintech, healthcare o e-commerce regolamentati.

L'analisi di Courier sui limiti delle notifiche Expo in ambito enterprise evidenzia la mancanza di linee guida pratiche su consent logging, audit trail e minimizzazione dell'esposizione di payload sensibili. Il takeaway tecnico è semplice:

  • Non inserire dati aziendali sensibili nel testo della notifica o nei metadati del payload.
  • Logga le modifiche al consenso lato server.
  • Registra quale intento di notifica è stato inviato a quale token.
  • Usa gli ID nei payload e recupera i contenuti protetti dopo l'apertura dell'app.

Per i team che allineano le operazioni di rilascio con compliance degli app store e le pratiche di sicurezza API, le push dovrebbero rientrare nello stesso processo di revisione di auth, analytics e logging degli eventi backend.

Le notifiche push sono messaggi rivolti all'utente, ma sono anche un problema di sistemi distribuiti. Gestiscile con la stessa cura che riservi allo stato di auth e agli eventi di pagamento.

Cosa di solito funziona e cosa di solito si rompe

Di solito funziona Di solito si rompe
Richiedere il permesso dopo aver spiegato chiaramente il valore Mostrare il prompt al primo frame
Test su dispositivi reali Affidarsi alla registrazione del simulatore
Salvare i token con il contesto del device Un token per ogni record utente
Inviare piccoli payload di metadati Inserire blob grandi o sensibili
Gestire separatamente eventi foreground e tap Assumendo che tutte le notifiche seguano un unico percorso
Scadenza aggressiva dei token obsoleti Tentativi infiniti con token non validi

Un setup Expo push solido non è complicato. È questione di disciplina.


Se il tuo team rilascia spesso modifiche alla logica dell'app e ha bisogno di un controllo maggiore su release, rollback e visibilità della distribuzione, Capgo merita un'occhiata. Aiuta i team mobile a inviare aggiornamenti rapidamente senza attendere la revisione degli store, particolarmente utile quando flussi di notifica, logiche di routing o fix lato client devono raggiungere subito gli utenti.

Live updates per le app Capacitor

Quando un bug nel web-layer è live, rilascia la fix tramite Capgo invece di aspettare giorni l'approvazione degli store. Gli utenti ricevono l'update in background, mentre le modifiche native restano nel normale processo di review.

Ultimi articoli dal blog

Capgo ti offre gli insight migliori che ti servono per creare un'app mobile davvero professionale.