Salta al contenuto principale
Mobile Guide

Guida completa alle notifiche push di Expo 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 notifiche push di Expo 2026

Probabilmente sei arrivato al punto in cui l'app funziona, gli utenti hanno effettuato l'accesso e il product team ora 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 correttamente e nessuno sa spiegare perché i tap non aprono la schermata giusta.

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

Expo offre ai team React Native uno strato pratico sopra APNs e FCM, ed è proprio per questo che così tanti team lo usano. Ma il divario tra una demo e un'implementazione pronta per la produzione è reale. Il ciclo di vita dei token, il timing dei permessi, il setup dei listener, il design del payload e la pulizia del backend sono tutti fondamentali. Se rilasci anche frequenti modifiche alla logica dell'app, la necessità di disciplina operativa diventa ancora più critica, 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 Expo Push Notifications

Un Notifiche push di Expo il setup è molto attraente per un motivo principale. Elimina gran parte della complessità nativa della messaggistica 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 backend.

Questa astrazione non rende le notifiche push "meno reali". Cambia solo dove viene investito il tuo sforzo ingegneristico.

Il servizio è anche così veloce che le performance di solito non sono la prima preoccupazione. 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, according to l'analisi benchmark di Knock sul API di Expo. Questo dovrebbe rassicurare i team che temono che Expo sia adatto solo ai prototipi.

Cosa nasconde realmente Expo

Quando i team parlano di “Expo push”, spesso intendono diversi concetti 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 direttamente i token specifici della piattaforma.
  • Contratto della richiesta: Inviate un payload tramite POST all'API di Expo, invece di integrare direttamente le API dei provider nativi.

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

Regola pratica: Considerate Expo come un reliable transport layer, 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. La prontezza per la produzione significa altro:

Preoccupazione Mentalità da demo Mentalità da produzione
Permessi Chiedi subito Chiedi all'IA, dopo aver compreso il valore per l'utente
Token Save once Refresh, deduplicazione, scadenza e riconciliazione
Payload Inserisci tutto qui data Mantieni i payload piccoli e orientati all'azione
Comportamento dell'app Mostra un alert Naviga correttamente e gestisci lo stato in foreground
Operazioni Test manuali Receipt, cleanup, logs 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, ma l'app potrebbe comportarsi 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 coerente con il tuo percorso di build. Se lavori oltre Expo Go, ti conviene allineare il tuo workflow di rilascio con la guida di Capgo sull'alternativa a Expo EAS, poiché il comportamento delle notifiche va spesso 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 sia Expo a risolvere quelle compatibili.

Aggiungi la configurazione a livello di progetto

Mantieni la config esplicita. Un setup app.json o app.config.js deve riflettere 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 fondamentali:

  • Bundle identifier e package name devono corrispondere all'app che pubblichi effettivamente.
  • Il plugin delle notifiche assicura che il progetto nativo riceva il setup necessario durante il build.
  • L'EAS project ID è importante quando il recupero del token richiede che l'app sia associata al corretto progetto Expo.

Imposta un notification handler subito

Molti tutorial base aspettano troppo per definire il comportamento delle notifiche. Non farlo. Configurale all'avvio dell'app per rendere prevedibile il comportamento in foreground.

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 prodotto: un'app di chat e una di pagamenti non faranno le stesse scelte.

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

Android richiede la configurazione dei canali

Nella pratica, i canali di notifica Android non sono opzionali. Se li salti, i tuoi alert 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. Mantieni gli ID dei canali stabili: cambiarli senza un motivo preciso renderà il comportamento delle notifiche difficile da gestire in seguito.

Richiesta dei permessi e cattura dei Push Token

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

Le richieste di permesso richiedono tempismo, consapevolezza della piattaforma e una gestione asincrona disciplinata. La cattura del token deve avvenire solo su un dispositivo fisico, solo dopo la risoluzione dei permessi e solo se sei pronto a salvare il risultato sul tuo backend immediatamente.

Un diagramma passo-passo che mostra il processo di ottenimento e salvataggio dei token delle notifiche push di Expo.

La funzione client che dovrebbe essere il tuo baseline

Usa una funzione come questa come punto di partenza:

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 un sacco di rumore pur sembrando innocuo. I team esperti richiedono i permessi condizionalmente solo quando Device.isDevice è vero, 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 di Eagerworks sull'implementazione delle notifiche Expo.

Ecco perché il controllo si trova all'inizio della funzione. Non nasconderlo dietro un helper. Rendilo esplicito.

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

Chiedi il permesso al momento giusto

Non chiederli nella splash screen. Non chiederli prima che l'utente ne capisca il valore. Il momento migliore è solitamente dopo un'azione dell'utente che renda concreti i vantaggi delle notifiche, come attivare gli aggiornamenti sulla consegna, unirsi a una conversazione o salvare un elemento.

Una buona implementazione segue solitamente 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 questo passaggio finale che molte app falliscono. Recuperano il token, lo loggano localmente e rimandano la registrazione al backend. In seguito, il supporto non saprà 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 gestiscono app con rilasci frequenti, è 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 proprio server

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

Ecco un esempio minimale in stile Node usando 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 Punta all'Expo Push Token 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 dei suoni di sistema Usali con moderazione per avvisi critici
data Metadati specifici dell'app Preferisci ID e hint di routing al contenuto ricco

L'oggetto data l'oggetto è il punto in cui i workflow di prodotto diventano utili. Puoi passare un tipo e un ID record, lasciando che l'app recuperi i dati più recenti quando l'utente clicca. È più sicuro che inserire 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 i limiti di circa 4 KB possono essere scartati. Un pattern affidabile è inviare piccoli payload di metadati come { "type": "new_review", "id": 123 } invece di grandi JSON o media inline. È un approccio che funziona nei sistemi reali: i payload piccoli falliscono meno spesso e sono più resilienti ai cambiamenti della logica dell'app.

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 si aggiungono altre responsabilità:

  • Persisti i tentativi di invio: Salva l'intento della notifica con user ID, token, tipo di payload e timestamp.
  • Separa la generazione dei contenuti dal trasporto: Costruisci 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 utilizzi altrove.

Prima di fare il debug dei 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 modificando la navigazione code. Inizia validando il token, la struttura del payload e lo stato dei permessi.

Gestire le notifiche in entrata 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 applicazioni mobile in stato foreground e background.

La ricezione in foreground e la risposta dell'utente sono eventi diversi

Un setup 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 differenti.

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 è resiliente perché il payload contiene suggerimenti di routing, non interi documenti. Se l'ordine è cambiato dall'invio della notifica, l'app può recuperare lo stato attuale dal server dopo la navigazione.

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

Foreground behavior should match user context

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

Ecco perché il tuo listener in foreground dovrebbe biforcarsi per rotta 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 più velocemente la notification fatigue, anche se la consegna è tecnicamente corretta.

Best Practice in 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 assunzione 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 a vita. I token possono cambiare dopo una reinstallazione, aggiornamenti dell'OS o altri eventi del ciclo di vita. Se un token ritorna 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 accesso
  • stato (es. attivo, scaduto o revocato)

Non limitarti a salvare un campo token nella tabella user. Gli utenti hanno più dispositivi e i dispositivi cambiano stato.

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 App Store e aggiornamenti OTA, aspetto fondamentale per i team che rilasciano modifiche live, poiché l'affidabilità delle notifiche dipende dallo stato del token e dalla sincronizzazione 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 hobbistiche, ma non per prodotti fintech, sanitari o di commercio regolamentato.

L'analisi di Courier sui limiti delle notifiche Expo per le aziende 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 i cambiamenti di 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 push notification 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 funziona e cosa solitamente si rompe

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

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


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

Live update per le app Capacitor

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

Le ultime dal nostro blog

Capgo ti offre i migliori insight per creare un'app mobile davvero professionale.