欢迎参加我们将于 2022 年 10 月 18 日举办的 Firebase 峰会(线上线下同时进行),了解 Firebase 如何帮助您加快应用开发速度、满怀信心地发布应用并在之后需要时轻松地扩大应用规模。立即报名

Comprendere la consegna dei messaggi

FCM fornisce tre set di strumenti per aiutarti a ottenere informazioni dettagliate sulla consegna dei messaggi:

  • Rapporti di consegna dei messaggi della console Firebase
  • Metriche di consegna dell'SDK Android aggregate dall'API dei dati di messaggistica cloud di Firebase
  • Esportazione completa dei dati su Google BigQuery

Gli strumenti di reporting descritti in questa pagina richiedono tutti Google Analytics per funzionare. Se Google Analytics non è abilitato per il tuo progetto, puoi configurarlo nella scheda Integrazioni delle impostazioni del tuo progetto Firebase.

Tieni presente che i rapporti di molte delle statistiche in questa pagina sono soggetti a ritardi fino a 24 ore a causa del batching dei dati analitici.

Rapporti di consegna dei messaggi

Nella scheda Rapporti della console Firebase, puoi visualizzare i seguenti dati per i messaggi inviati agli SDK FCM della piattaforma Android o Apple, inclusi quelli inviati tramite il compositore di notifiche e le API FCM:

  • Invii: il messaggio di dati o il messaggio di notifica è stato messo in coda per la consegna o è stato passato correttamente a un servizio di terze parti come APN per la consegna. Per ulteriori informazioni, vedere la durata di un messaggio .
  • Ricevuto (disponibile solo su dispositivi Android): il messaggio di dati o il messaggio di notifica è stato ricevuto dall'app. Questi dati sono disponibili quando sul dispositivo Android ricevente è installato FCM SDK 18.0.1 o versioni successive.
  • Impressioni (disponibili solo per i messaggi di notifica su dispositivi Android): la notifica di visualizzazione è stata visualizzata sul dispositivo mentre l'app è in background.
  • Apre: l'utente ha aperto il messaggio di notifica. Segnalato solo per le notifiche ricevute quando l'app è in background.

Questi dati sono disponibili per tutti i messaggi con un payload di notifica e tutti i messaggi di dati etichettati . Per ulteriori informazioni sulle etichette, consulta Aggiunta di etichette analitiche ai messaggi .

Durante la visualizzazione dei rapporti sui messaggi, puoi impostare un intervallo di date per i dati visualizzati, con l'opzione di esportarli in CSV. Puoi anche filtrare in base a questi criteri:

  • Piattaforma (iOS o Android)
  • App
  • Etichette analitiche personalizzate

Aggiunta di etichette analitiche ai messaggi

L'etichettatura dei messaggi è molto utile per l'analisi personalizzata, consentendo di filtrare le statistiche di consegna in base a etichette o set di etichette. Puoi aggiungere un'etichetta a qualsiasi messaggio inviato tramite l'API HTTP v1 impostando il campo fcmOptions.analyticsLabel nell'oggetto messaggio o nei campi AndroidFcmOptions o ApnsFcmOptions specifici della piattaforma.

Le etichette di Analytics sono stringhe di testo nel formato ^[a-zA-Z0-9-_.~%]{1,50}$ . Le etichette possono includere lettere minuscole e maiuscole, numeri e i seguenti simboli:

  • -
  • ~
  • %

La lunghezza massima è di 50 caratteri. Puoi specificare fino a 100 etichette univoche al giorno; i messaggi con etichette aggiunte oltre tale limite non vengono segnalati.

Nella scheda Rapporti di messaggistica della console Firebase, puoi cercare in un elenco di tutte le etichette esistenti e applicarle singolarmente o in combinazione per filtrare le statistiche visualizzate.

Dati di consegna aggregati tramite FCM Data API

L'API Firebase Cloud Messaging Data ti consente di recuperare informazioni che possono aiutarti a comprendere i risultati delle richieste di messaggi mirate alle applicazioni Android. L'API fornisce dati aggregati su tutti i dispositivi Android abilitati alla raccolta dati in un progetto. Ciò include i dettagli sulla percentuale di messaggi consegnati senza ritardo e quanti messaggi sono stati ritardati o eliminati all'interno del livello di trasporto Android . La valutazione di questi dati può rivelare tendenze generali nella consegna dei messaggi e aiutarti a trovare modi efficaci per migliorare le prestazioni delle tue richieste di invio. Per informazioni sulla disponibilità dell'intervallo di date nei rapporti, vedere Sequenze temporali dei dati aggregati .

L'API fornisce tutti i dati disponibili per una determinata applicazione. Consulta la documentazione di riferimento dell'API .

Come vengono suddivisi i dati?

I dati di consegna sono suddivisi per applicazione, data ed etichetta di analisi . Una chiamata all'API restituirà i dati per ogni combinazione di data, applicazione ed etichetta di analisi. Ad esempio, un singolo oggetto JSON androidDeliveryData sarebbe simile a questo:

 {
  "appId": "1:23456789:android:a93a5mb1234efe56",
  "date": {
    "year": 2021,
    "month": 1,
    "day": 1
  },
  "analyticsLabel": "foo",
  "data": {
    "countMessagesAccepted": "314159",
    "messageOutcomePercents": {
      "delivered": 71,
      "pending": 15
    },
   "deliveryPerformancePercents": {
      "deliveredNoDelay": 45,
      "delayedDeviceOffline": 11
    }
  }

Come interpretare le metriche

I dati di consegna delineano la percentuale di messaggi che si adattano a ciascuna delle seguenti metriche. È possibile che un singolo messaggio rientri in più metriche. A causa delle limitazioni nel modo in cui raccogliamo i dati e del livello di granularità a cui abbiamo aggregato le metriche, alcuni risultati dei messaggi non sono affatto rappresentati nelle metriche, quindi le percentuali seguenti non si sommeranno al 100%.

Conteggio messaggi accettati

L'unico conteggio incluso nel set di dati è il conteggio dei messaggi che sono stati accettati da FCM per la consegna ai dispositivi Android. Tutte le percentuali utilizzano questo valore come denominatore. Tieni presente che questo conteggio non includerà i messaggi destinati agli utenti che hanno disabilitato la raccolta di informazioni sull'utilizzo e sulla diagnostica sui propri dispositivi.

Percentuali di esito del messaggio

I campi inclusi nell'oggetto MessageOutcomePercents forniscono informazioni sui risultati delle richieste di messaggi. Le categorie sono tutte mutualmente esclusive. Può rispondere a domande come "I miei messaggi vengono consegnati?" e "Cosa causa l'eliminazione dei messaggi?"

Ad esempio, un valore elevato per il campo droppedTooManyPendingMessages potrebbe segnalare che le istanze dell'app stanno ricevendo volumi di messaggi non comprimibili che superano il limite di 100 messaggi in sospeso di FCM. Per mitigare questo problema, assicurati che la tua app gestisca le chiamate a onDeletedMessages e considera l'invio di messaggi comprimibili. Allo stesso modo, percentuali elevate per droppedDeviceInactive potrebbero essere un segnale per aggiornare i token di registrazione sul tuo server, rimuovere i token obsoleti e annullarne l'iscrizione dagli argomenti. Consulta Gestire i token di registrazione FCM per le migliori pratiche in quest'area.

Percentuali di prestazione di consegna

I campi dell'oggetto DeliveryPerformancePercents forniscono informazioni sui messaggi che sono stati recapitati correttamente. Può rispondere a domande come "I miei messaggi sono stati ritardati?" e "Perché i messaggi sono in ritardo?" Ad esempio, un valore elevato per delayedMessageThrottled indicherebbe chiaramente che stai superando i limiti massimi per dispositivo e dovrebbe regolare la velocità di invio dei messaggi.

Percentuali di analisi dei messaggi

Questo oggetto fornisce informazioni aggiuntive su tutti i messaggi inviati. Il campo priorityLowered esprime la percentuale di messaggi accettati con priorità ridotta da HIGH a NORMAL . Se questo valore è alto, prova a inviare meno messaggi ad alta priorità o assicurati di visualizzare sempre una notifica quando viene inviato un messaggio ad alta priorità. Consulta la nostra documentazione sulla priorità dei messaggi per ulteriori informazioni

In che cosa differiscono questi dati dai dati esportati in BigQuery?

L'esportazione BigQuery fornisce registri dei messaggi individuali sull'accettazione dei messaggi da parte del back-end FCM e sulla consegna dei messaggi nell'SDK sul dispositivo (passaggi 2 e 4 dell'architettura FCM ). Questi dati sono utili per garantire che i singoli messaggi siano stati accettati e consegnati. Ulteriori informazioni sull'esportazione dei dati BigQuery nella sezione successiva.

Al contrario, l'API Firebase Cloud Messaging Data fornisce dettagli aggregati su ciò che accade specificamente nel livello di trasporto Android (o passaggio 3 dell'architettura FCM ). Questi dati forniscono informazioni dettagliate sulla consegna dei messaggi dai backend FCM all'SDK Android. È particolarmente utile per mostrare le tendenze sul motivo per cui i messaggi sono stati ritardati o eliminati durante questo trasporto.

In alcuni casi, è possibile che i due set di dati non corrispondano esattamente a causa di quanto segue:

  • Le metriche aggregate campionano solo una parte di tutti i messaggi
  • Le metriche aggregate sono arrotondate
  • Non presentiamo metriche al di sotto di una soglia di privacy
  • Manca una parte dei risultati dei messaggi a causa delle ottimizzazioni nel modo in cui gestiamo il grande volume di traffico.

Limitazioni dell'API

Cronologia dei dati aggregati

L'API restituirà 7 giorni di dati storici; tuttavia, i dati restituiti da questa API subiranno un ritardo fino a 5 giorni. Ad esempio, il 20 gennaio sarebbero disponibili i dati per il 9 gennaio - 15 gennaio, ma non per il 16 gennaio o successivi. Inoltre, i dati vengono forniti al meglio. In caso di interruzione dei dati, FCM lavorerà per risolvere il problema e non eseguirà il backfill dei dati dopo che il problema è stato risolto. In caso di interruzioni maggiori, i dati potrebbero non essere disponibili per una settimana o più.

Copertura dei dati

Le metriche fornite dall'API Firebase Cloud Messaging Data hanno lo scopo di fornire informazioni dettagliate sulle tendenze generali della consegna dei messaggi. Tuttavia, non forniscono una copertura del 100% di tutti gli scenari di messaggi. Gli scenari seguenti sono risultati noti non riflessi nelle metriche.

Messaggi compressi

I messaggi che sono stati compressi da un altro messaggio non vengono visualizzati nel set di dati.

Messaggi a dispositivi inattivi

I messaggi inviati a dispositivi inattivi possono o non possono essere visualizzati nel set di dati a seconda del percorso dati che prendono. Ciò può comportare un conteggio errato nei campi droppedDeviceInactive e pending .

Messaggi a dispositivi con determinate preferenze dell'utente

Gli utenti che hanno disabilitato la raccolta delle informazioni di utilizzo e diagnostiche sui propri dispositivi non vedranno i loro messaggi inclusi nel nostro conteggio, in linea con le loro preferenze.

Arrotondamenti e minimi

FCM arrotonda ed esclude deliberatamente i conteggi in cui i volumi non sono sufficientemente grandi.

Esportazione dati BigQuery

Puoi esportare i dati dei tuoi messaggi in BigQuery per ulteriori analisi. BigQuery ti consente di analizzare i dati utilizzando BigQuery SQL, esportarli in un altro provider cloud o utilizzare i dati per i tuoi modelli ML personalizzati. Un'esportazione in BigQuery include tutti i dati disponibili per i messaggi, indipendentemente dal tipo di messaggio o dal fatto che il messaggio venga inviato tramite l'API o il compositore di notifiche.

Per i messaggi inviati a dispositivi con le seguenti versioni minime dell'SDK FCM, hai la possibilità aggiuntiva di abilitare l'esportazione dei dati di recapito dei messaggi per la tua app:

  • Android 20.1.0 o versioni successive.
  • iOS 8.6.0 o versioni successive
  • Firebase Web SDK 9.0.0 o versioni successive

Vedi sotto per i dettagli sull'abilitazione dell'esportazione dei dati per Android e iOS .

Per iniziare, collega il tuo progetto a BigQuery:

  1. Scegli una delle seguenti opzioni:

    • Apri il compositore di notifiche , quindi fai clic su Accedi a BigQuery nella parte inferiore della pagina.

    • Dalla pagina Integrazioni nella console Firebase, fai clic su Link nella scheda BigQuery .

      Questa pagina mostra le opzioni di esportazione FCM per tutte le app abilitate per FCM nel progetto.

  2. Segui le istruzioni sullo schermo per abilitare BigQuery.

Per ulteriori informazioni, fai riferimento a Collegamento di Firebase a BigQuery .

Quando abiliti l'esportazione BigQuery per Cloud Messaging:

  • Firebase esporta i tuoi dati in BigQuery. Tieni presente che il completamento della propagazione iniziale dei dati per l'esportazione può richiedere fino a 48 ore.

  • Dopo aver creato il set di dati, la posizione non può essere modificata, ma puoi copiare il set di dati in una posizione diversa o spostare (ricreare) manualmente il set di dati in una posizione diversa. Per ulteriori informazioni, consulta Modifica della posizione del set di dati .

  • Firebase imposta sincronizzazioni regolari dei tuoi dati dal tuo progetto Firebase a BigQuery. Queste operazioni di esportazione giornaliere iniziano alle 4:00 ora del Pacifico e di solito terminano in 24 ore.

  • Per impostazione predefinita, tutte le app del tuo progetto sono collegate a BigQuery e tutte le app che aggiungi in seguito al progetto vengono automaticamente collegate a BigQuery. Puoi gestire quali app inviano dati .

Per disattivare l'esportazione BigQuery, scollega il tuo progetto nella console di Firebase.

Abilita l'esportazione dei dati di consegna dei messaggi

I dispositivi Android con FCM SDK 20.1.0 o versioni successive possono abilitare l'esportazione dei dati di recapito dei messaggi della loro app. L'esportazione dei dati è disabilitata per impostazione predefinita a livello di app . L'abilitazione a livello di codice a livello di istanza dell'app consente di chiedere agli utenti finali l'autorizzazione ad analizzare i dati di recapito dei messaggi (opzione consigliata). Quando sono impostati entrambi, il valore del livello dell'istanza dell'app sovrascrive il valore del livello dell'app.

Prima di abilitare queste opzioni, devi prima creare il collegamento FCM-BiqQuery per il tuo progetto come descritto in BigQuery Data Export .

Abilita l'esportazione dei dati di consegna per le istanze dell'app

Nella maggior parte dei casi, ti consigliamo di abilitare l'esportazione dei dati di recapito dei messaggi solo a livello di istanza dell'app e di lasciarla disabilitata a livello di app.

 FirebaseMessaging.getInstance().setDeliveryMetricsExportToBigQuery(true)

Abilita l'esportazione dei dati di consegna per un'app

Se preferisci abilitare l'esportazione a livello di app, assicurati di non chiamare il metodo setDeliveryMetricsExportToBigQuery e aggiungi la seguente proprietà all'oggetto applicazione nel manifest dell'app:

<application>
  <meta-data android:name="delivery_metrics_exported_to_big_query_enabled"
      android:value="true" />
</application>

Quali dati vengono esportati in BigQuery?

Tieni presente che il targeting di token obsoleti o registrazioni inattive potrebbe gonfiare alcune di queste statistiche.

Lo schema della tabella esportata è:

_TEMPO DI PARTIZIONE SEGNALIBRO Questa pseudo colonna contiene un timestamp per l'inizio del giorno (in UTC) in cui sono stati caricati i dati. Per la partizione AAAAMMGG, questa pseudo colonna contiene il valore TIMESTAMP('AAAA-MM-GG').
event_timestamp SEGNALIBRO Timestamp dell'evento come registrato dal server
progetto numero NUMERO INTERO Il numero del progetto identifica il progetto che ha inviato il messaggio
messaggio_id CORDA L'ID messaggio identifica un messaggio. Generato dall'ID app e dal timestamp, l'ID messaggio potrebbe, in alcuni casi, non essere univoco a livello globale.
id_istanza CORDA L'ID univoco dell'app a cui viene inviato il messaggio (se disponibile). Può essere un ID istanza o un ID installazione Firebase.
tipo_messaggio CORDA Il tipo del messaggio. Può essere messaggio di notifica o messaggio di dati. L'argomento viene utilizzato per identificare il messaggio originale per l'invio di un argomento o di una campagna; i messaggi successivi sono una notifica o un messaggio di dati.
piattaforma_sdk CORDA La piattaforma dell'app del destinatario
nome dell'applicazione CORDA Il nome del pacchetto per le app Android o l'ID bundle per le app iOS
chiave_collasso CORDA La chiave di compressione identifica un gruppo di messaggi che possono essere compressi. Quando un dispositivo non è connesso, solo l'ultimo messaggio con una determinata chiave di compressione viene messo in coda per l'eventuale consegna
priorità NUMERO INTERO La priorità del messaggio. I valori validi sono "normale" e "alto". Su iOS, corrispondono alle priorità APN 5 e 10
ttl NUMERO INTERO Questo parametro specifica per quanto tempo (in secondi) il messaggio deve essere conservato nell'archivio FCM se il dispositivo è offline
argomento CORDA Il nome dell'argomento a cui è stato inviato un messaggio (se applicabile)
bulk_id NUMERO INTERO L'ID bulk identifica un gruppo di messaggi correlati, ad esempio un particolare invio a un argomento
evento CORDA Il tipo di evento. I valori possibili sono:
  • MESSAGE_ACCEPTED: il messaggio è stato ricevuto dal server FCM e la richiesta è valida;
  • MESSAGE_DELIVERED: il messaggio è stato consegnato all'SDK FCM dell'app sul dispositivo. Per impostazione predefinita, questo campo non viene propagato. Per abilitare, segui le istruzioni fornite in setDeliveryMetricsExportToBigQuery(boolean) .
  • MISSING_REGISTRAATIONS: richiesta respinta per mancata registrazione;
  • UNAUTHORIZED_REGISTRATION: il messaggio è stato rifiutato perché il mittente non è autorizzato a inviare alla registrazione;
  • MESSAGE_RECEIVED_INTERNAL_ERROR: si è verificato un errore non specificato durante l'elaborazione della richiesta del messaggio;
  • MISMATCH_SENDER_ID: la richiesta di invio di un messaggio è stata rifiutata a causa di una mancata corrispondenza tra l'id mittente che invia il messaggio e quello dichiarato per l'end-point;
  • QUOTA_EXCEEDED: la richiesta di invio messaggio è stata rifiutata per quota insufficiente;
  • INVALID_REGISTRATION: la richiesta di invio di un messaggio è stata rifiutata a causa di una registrazione non valida;
  • INVALID_PACKAGE_NAME: la richiesta di invio di un messaggio è stata rifiutata a causa di un nome del pacchetto non valido;
  • INVALID_APNS_CREDENTIAL: la richiesta di invio di un messaggio è stata rifiutata a causa di un certificato APNS non valido;
  • INVALID_PARAMETERS: la richiesta di invio di un messaggio è stata rifiutata per parametri non validi;
  • PAYLOAD_TOO_LARGE: la richiesta di invio di un messaggio è stata rifiutata a causa di un payload superiore al limite;
  • AUTHENTICATION_ERROR: la richiesta di invio di un messaggio è stata rifiutata a causa di un errore di autenticazione (verificare la chiave API utilizzata per inviare il messaggio);
  • INVALID_TTL: la richiesta di invio di un messaggio è stata rifiutata a causa di un TTL non valido.
etichetta_analitica CORDA Con l' API HTTP v1 , è possibile impostare l'etichetta di analisi durante l'invio del messaggio, in modo da contrassegnare il messaggio per scopi di analisi

Cosa puoi fare con i dati esportati?

Le sezioni seguenti offrono esempi di query che puoi eseguire in BigQuery sui dati FCM esportati.

Conta i messaggi inviati dall'app

SELECT app_name, COUNT(1)
FROM `project ID.firebase_messaging.data`
WHERE
  _PARTITIONTIME = TIMESTAMP('date as YYYY-MM-DD')
  AND event = 'MESSAGE_ACCEPTED'
  AND message_id != ''
GROUP BY 1;

Conta le istanze dell'app uniche prese di mira dai messaggi

SELECT COUNT(DISTINCT instance_id)
FROM `project ID.firebase_messaging.data`
WHERE
  _PARTITIONTIME = TIMESTAMP('date as YYYY-MM-DD')
  AND event = 'MESSAGE_ACCEPTED';

Conta i messaggi di notifica inviati

SELECT COUNT(1)
FROM `project ID.firebase_messaging.data`
WHERE
  _PARTITIONTIME = TIMESTAMP('date as YYYY-MM-DD')
  AND event = 'MESSAGE_ACCEPTED'
  AND message_type = 'DISPLAY_NOTIFICATION';

Conta i messaggi di dati inviati

SELECT COUNT(1)
FROM `project ID.firebase_messaging.data`
WHERE
  _PARTITIONTIME = TIMESTAMP('date as YYYY-MM-DD')
  AND event = 'MESSAGE_ACCEPTED'
  AND message_type = 'DATA_MESSAGE';

Conta i messaggi inviati a un argomento o a una campagna

SELECT COUNT(1)
FROM `project ID.firebase_messaging.data`
WHERE
  _PARTITIONTIME = TIMESTAMP('date as YYYY-MM-DD')
  AND event = 'MESSAGE_ACCEPTED'
  AND bulk_id = your bulk id AND message_id != '';

Per tenere traccia degli eventi per un messaggio inviato a un argomento particolare, modifica questa query per sostituire AND message_id != '' con AND message_id = <your message id>; .

Calcola la durata del fanout per un determinato argomento o campagna

L'ora di inizio del fanout è quando viene ricevuta la richiesta originale e l'ora di fine è l'ora in cui viene creato l'ultimo singolo messaggio destinato a una singola istanza.

SELECT
  TIMESTAMP_DIFF(
    end_timestamp, start_timestamp, MILLISECOND
  ) AS fanout_duration_ms,
  end_timestamp,
  start_timestamp
FROM (
    SELECT MAX(event_timestamp) AS end_timestamp
    FROM `project ID.firebase_messaging.data`
    WHERE
      _PARTITIONTIME = TIMESTAMP('date as YYYY-MM-DD')
      AND event = 'MESSAGE_ACCEPTED'
      AND bulk_id = your bulk id
  ) sent
  CROSS JOIN (
    SELECT event_timestamp AS start_timestamp
    FROM `project ID.firebase_messaging.data`
    WHERE
      _PARTITIONTIME = TIMESTAMP('date as YYYY-MM-DD')
      AND event = 'MESSAGE_ACCEPTED'
      AND bulk_id = your bulk id
      AND message_type = 'TOPIC'
  ) initial_message;

Conteggio percentuale di messaggi consegnati

SELECT
  messages_sent,
  messages_delivered,
  messages_delivered / messages_sent * 100 AS percent_delivered
FROM (
    SELECT COUNT(DISTINCT CONCAT(message_id, instance_id)) AS messages_sent
    FROM `project ID.firebase_messaging.data`
    WHERE
      _PARTITIONTIME = TIMESTAMP('date as YYYY-MM-DD')
      AND event = 'MESSAGE_ACCEPTED'
  ) sent
  CROSS JOIN (
    SELECT COUNT(DISTINCT CONCAT(message_id, instance_id)) AS messages_delivered
    FROM `project ID.firebase_messaging.data`
    WHERE
      _PARTITIONTIME = TIMESTAMP('date as YYYY-MM-DD')
      AND (event = 'MESSAGE_DELIVERED'
      AND message_id
      IN (
        SELECT message_id FROM `project ID.firebase_messaging.data`
        WHERE
          _PARTITIONTIME = TIMESTAMP('date as YYYY-MM-DD')
          AND event = 'MESSAGE_ACCEPTED'
        GROUP BY 1
      )
  ) delivered;

Tieni traccia di tutti gli eventi per un determinato ID messaggio e ID istanza

SELECT *
FROM `project ID.firebase_messaging.data`
WHERE
    _PARTITIONTIME = TIMESTAMP('date as YYYY-MM-DD')
    AND message_id = 'your message id'
    AND instance_id = 'your instance id'
ORDER BY event_timestamp;

Calcola la latenza per un determinato ID messaggio e ID istanza

SELECT
  TIMESTAMP_DIFF(
    MAX(delivered_time), MIN(accepted_time), MILLISECOND
  ) AS latency_ms
FROM (
    SELECT event_timestamp AS accepted_time
    FROM `project ID.firebase_messaging.data`
    WHERE
      _PARTITIONTIME = TIMESTAMP('date as YYYY-MM-DD')
      AND message_id = 'your message id'
      AND instance_id = 'your instance id'
      AND event = 'MESSAGE_ACCEPTED'
  ) sent
  CROSS JOIN (
    SELECT event_timestamp AS delivered_time
    FROM `project ID.firebase_messaging.data`
    WHERE
      _PARTITIONTIME = TIMESTAMP('date as YYYY-MM-DD') AND
      message_id = 'your message id' AND instance_id = 'your instance id'
      AND (event = 'MESSAGE_DELIVERED'
  ) delivered;