Join us for Firebase Summit on November 10, 2021. Tune in to learn how Firebase can help you accelerate app development, release with confidence, and scale with ease. Register

Comprendre la livraison des messages

FCM propose trois ensembles d'outils pour vous aider à mieux comprendre la livraison des messages :

  • Rapports de livraison des messages de la console Firebase et analyse de l'entonnoir de notification
  • Métriques de livraison du SDK Android agrégées à partir de l'API Firebase Cloud Messaging Data
  • Exportation complète des données vers Google BigQuery

Les outils de reporting décrits dans cette page nécessitent tous Google Analytics pour fonctionner. Si Google Analytics est pas activé pour votre projet, vous pouvez le configurer dans l' intégration onglet de paramètres de votre projet Firebase.

Gardez à l'esprit que la communication de nombreuses statistiques sur cette page est sujette à des retards pouvant aller jusqu'à 24 heures en raison du regroupement des données d'analyse.

Rapports de livraison de messages

Dans le Rapports onglet dans la console Firebase, vous pouvez afficher les données suivantes pour les messages envoyés à Android ou iOS FCM, y compris ceux SDKs envoyés via le Notifications compositeur et les API de la FCM:

  • Envois — Le message de données ou le message de notification a été mis en file d'attente pour la livraison ou a été transmis avec succès à un service tiers comme les APN pour la livraison. Voir la vie d'un message pour plus d' informations.
  • Reçu (disponible uniquement sur les appareils Android) — Le message de données ou le message de notification a été reçu par l'application. Ces données sont disponibles lorsque l'appareil Android récepteur dispose du SDK FCM 18.0.1 ou supérieur.
  • Impressions (disponible uniquement pour les messages de notification sur les appareils Android) — La notification d'affichage a été affichée sur l'appareil pendant que l'application est en arrière-plan.
  • Ouvre — L'utilisateur a ouvert le message de notification. Signalé uniquement pour les notifications reçues lorsque l'application est en arrière-plan.

Ces données sont disponibles pour tous les messages avec une charge utile de notification et tous étiquetés messages de données . Pour en savoir plus sur les étiquettes, voir Ajout d' étiquettes d'analyse des messages .

Lors de l'affichage des rapports de messages, vous pouvez définir une plage de dates pour les données affichées, avec la possibilité d'exporter au format CSV. Vous pouvez également filtrer selon ces critères :

  • Plateforme (iOS ou Android)
  • Application
  • Étiquettes d'analyse personnalisées

Ajout d'étiquettes d'analyse aux messages

L'étiquetage des messages est très utile pour l'analyse personnalisée, vous permettant de filtrer les statistiques de livraison par étiquettes ou ensembles d'étiquettes. Vous pouvez ajouter une étiquette à un message envoyé via HTTP v1 API en définissant le fcmOptions.analyticsLabel champ dans le message de l' objet, ou dans les plates-formes spécifiques AndroidFcmOptions ou ApnsFcmOptions champs.

Étiquettes Analytics sont des chaînes de texte dans le format ^[a-zA-Z0-9-_.~%]{1,50}$ . Les étiquettes peuvent inclure des lettres minuscules et majuscules, des chiffres et les symboles suivants :

  • -
  • ~
  • %

La longueur maximale est de 50 caractères. Vous pouvez spécifier jusqu'à 100 étiquettes uniques par jour ; les messages avec des libellés ajoutés au-delà de cette limite ne sont pas signalés.

Dans la console Firebase messagerie onglet Rapports, vous pouvez rechercher une liste de toutes les étiquettes existantes et les appliquer seuls ou en combinaison pour filtrer les statistiques affichées.

Analyse de l'entonnoir de notification

Une analyse intégrée de l'entonnoir de notification vous montre comment vos utilisateurs répondent à des notifications particulières envoyées depuis la console Firebase. Cette vue inclut des données pour les appareils iOS et Android ciblés dans ces catégories :

  • Notifications envoyées — Le message a été mis en file d'attente pour la livraison ou a été transmis avec succès à un service tiers comme les APN pour la livraison. Notez que le ciblage de jetons périmés ou d'enregistrements inactifs peut gonfler ces statistiques.
  • Notifications ouvertes — Le nombre de notifications ouvertes. Signalé uniquement pour les notifications reçues lorsque l'application est en arrière-plan.
  • Le nombre d'utilisateurs uniques qui ont déclenché un événement de conversion, le cas échéant.

Pour voir l'analyse de l'entonnoir des notifications :

  1. Dans le compositeur Notifications, sélectionnez l' Notifications onglet.
  2. Cliquez sur un message terminé ou en cours dans la liste des messages. Une vue étendue comprenant une analyse en entonnoir s'affiche.

Les rapports d'analyse sont mis à jour périodiquement, mais il peut y avoir un certain délai entre le moment où un utilisateur ouvre la notification et le moment où les données d'événement sont disponibles dans la console. En plus de ces rapports sous l' Notifications onglet, vous pouvez également créer des entonnoirs personnalisés dans Google Analytics pour visualiser le taux d'achèvement d'une séquence d'étapes dans votre application.

Données de livraison agrégées via l'API de données FCM

L'API Firebase Cloud Messaging Data vous permet de récupérer des informations qui peuvent vous aider à comprendre les résultats des demandes de messages ciblées sur les applications Android. L'API fournit des données agrégées sur tous les appareils Android compatibles avec la collecte de données dans un projet. Cela comprend des détails sur le pourcentage de messages délivrés sans délai ainsi que le nombre de messages ont été reportés ou abandonnés dans le Transport Layer Android . L'évaluation de ces données peut révéler des tendances générales dans la livraison des messages et vous aider à trouver des moyens efficaces d'améliorer les performances de vos demandes d'envoi.

L'API fournit toutes les données disponibles pour une application donnée. Voir la documentation de référence de l' API .

Comment les données sont-elles ventilées ?

Les données de livraison sont ventilées par l' application, la date et l' étiquette d'analyse . Un appel à l'API renverra des données pour chaque combinaison de date, d'application et d'étiquette d'analyse. Par exemple, un seul androidDeliveryData objet JSON ressemblerait à ceci:

 {
  "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
    }
  }

Comment interpréter les métriques

Les données de livraison décrivent le pourcentage de messages qui correspondent à chacune des métriques suivantes. Il est possible qu'un seul message corresponde à plusieurs métriques. En raison des limitations dans la façon dont nous recueillons les données et le niveau de granularité à laquelle nous avons regroupé les paramètres, certains résultats de message ne sont pas représentés dans les mesures du tout, donc les pourcentages ci - dessous ne correspondra pas à 100%.

Compter les messages acceptés

Le seul nombre inclus dans l'ensemble de données est le nombre de messages qui ont été acceptés par le FCM pour être livrés aux appareils Android. Tous les pourcentages utilisent cette valeur comme dénominateur. Gardez à l'esprit que ce décompte n'inclura pas les messages destinés aux utilisateurs qui ont désactivé la collecte d'informations d'utilisation et de diagnostic sur leurs appareils.

Message Résultat Pourcentages

Les champs inclus dans le MessageOutcomePercents objet de fournir des informations sur les résultats des demandes de message. Les catégories sont toutes mutuellement exclusives. Il peut répondre à des questions telles que « Mes messages sont-ils distribués ? » et « Qu'est-ce qui provoque la suppression des messages ? »

Par exemple, une valeur élevée pour le droppedTooManyPendingMessages champ pourrait signaler que les cas d'applications reçoivent des volumes de messages non réductibles dépassant la limite de la FCM de 100 messages en attente. Pour atténuer cela, assurez - vous que vos poignées d'applications appels à onDeletedMessages et envisager d' envoyer des messages pliables. De même, les pourcentages élevés pour droppedDeviceInactive pourrait être un signal à jetons d'enregistrement de mise à jour sur votre serveur, suppression des jetons périmés et les désabonnement de sujets. Voir Gérer les jetons d'enregistrement FCM pour les meilleures pratiques dans ce domaine.

Pourcentages de performances de livraison

Les champs de l' DeliveryPerformancePercents objet de fournir des informations sur les messages qui ont été livrés avec succès. Il peut répondre à des questions telles que « Mes messages ont-ils été retardés ? » et "Pourquoi les messages sont-ils retardés ?" Par exemple, une valeur élevée pour delayedMessageThrottled indiquerait clairement que vous dépassez les limites maximales par périphérique , et vous devez adapter le taux auquel vous envoyez des messages.

Pourcentages d'aperçu des messages

Cet objet fournit des informations supplémentaires sur tous les envois de messages. Le priorityLowered champ exprime le pourcentage de messages qui avait accepté la priorité de baissées HIGH à NORMAL en raison de seaux de veille app . Si cette valeur est élevée, essayez d'envoyer moins de messages de haute priorité ou assurez-vous de toujours afficher une notification lorsqu'un message de haute priorité est envoyé.

En quoi ces données diffèrent-elles des données exportées vers BigQuery ?

L'exportation BigQuery fournit des journaux de messages individuels au sujet de l' acceptation du message par le serveur de la FCM et la distribution des messages dans le SDK sur l'appareil (étapes 2 et 4 de l' architecture FCM ). Ces données sont utiles pour s'assurer que les messages individuels ont été acceptés et livrés. En savoir plus sur l' exportation de données BigQuery dans la section suivante.

En revanche, l'API de données de messagerie cloud Firebase fournit des détails agrégées sur ce qui se passe précisément dans la couche de transport Android (ou à l' étape 3 de l' architecture FCM ). Ces données fournissent spécifiquement un aperçu de la livraison des messages des backends FCM au SDK Android. Il est particulièrement utile pour montrer les tendances expliquant pourquoi les messages ont été retardés ou abandonnés pendant ce transport.

Dans certains cas, il est possible que les deux ensembles de données ne correspondent pas précisément pour les raisons suivantes :

  • Les métriques agrégées n'échantillonnent qu'une partie de tous les messages
  • Les métriques agrégées sont arrondies
  • Nous ne présentons pas de métriques en dessous d'un seuil de confidentialité
  • Une partie des résultats des messages est manquante en raison d'optimisations dans la façon dont nous gérons le grand volume de trafic.

Limites de l'API

Délai de données

Les données renvoyées par cette API seront retardées jusqu'à 5 jours. Par exemple, le 10 janvier, les données du 5 janvier seraient disponibles, mais pas celles du 6 janvier ou plus tard. De plus, les données sont fournies au mieux. En cas de panne de données, FCM s'efforcera de résoudre le problème et ne remplira pas les données une fois le problème résolu. En cas de pannes plus importantes, les données peuvent être indisponibles pendant une semaine ou plus.

Couverture des données

Les métriques fournies par l'API Firebase Cloud Messaging Data sont destinées à fournir un aperçu des grandes tendances de la livraison des messages. Cependant, ils ne fournissent pas une couverture à 100 % de tous les scénarios de messages. Les scénarios suivants sont des résultats connus qui ne sont pas reflétés dans les métriques.

Messages réduits

Les messages qui ont été effondrés par un autre message ne figurent pas dans l'ensemble de données.

Messages aux appareils inactifs

Les messages envoyés aux appareils inactifs peuvent ou non apparaître dans l'ensemble de données en fonction du chemin de données qu'ils empruntent. Cela peut entraîner des erreurs de comptage dans les champs « Périphérique inactif abandonné » et « En attente ».

Messages aux appareils avec certaines préférences utilisateur

Les utilisateurs qui ont désactivé la collecte d'informations d'utilisation et de diagnostic sur leurs appareils n'auront pas leurs messages inclus dans notre comptage, conformément à leurs préférences.

Arrondissements et minimums

FCM arrondit et exclut délibérément les décomptes lorsque les volumes ne sont pas assez importants.

Exportation de données BigQuery

Vous pouvez exporter vos données de message dans BigQuery pour une analyse ultérieure. BigQuery vous permet d'analyser les données à l'aide de BigQuery SQL, de les exporter vers un autre fournisseur cloud ou d'utiliser les données pour vos modèles de ML personnalisés. Une exportation vers BigQuery inclut toutes les données disponibles pour les messages, quel que soit le type de message ou si le message est envoyé via l'API ou le composeur de notifications.

Pour les messages envoyés aux appareils avec les versions minimales suivantes du SDK FCM, vous avez la possibilité supplémentaire d'activer l'exportation des données de livraison des messages pour votre application :

  • Android 20.1.0 ou supérieur.
  • iOS 8.6.0 ou supérieur
  • Firebase Web SDK 9.0.0 ou version ultérieure

Voir ci - dessous pour plus de détails sur l' activation de l' exportation des données pour Android et iOS .

Pour commencer, associez votre projet à BigQuery :

  1. Choisissez l'une des options suivantes :

    • Ouvrez le Notifications compositeur , puis cliquez sur Accès BigQuery au bas de la page.

    • De la Intégrations page dans la console Firebase, cliquez sur le lien dans la carte BigQuery.

      Cette page affiche les options d'exportation FCM pour toutes les applications compatibles FCM dans le projet.

  2. Suivez les instructions à l'écran pour activer BigQuery.

Reportez - vous à Lien Firebase vers BigQuery pour plus d' informations.

Après avoir associé votre projet à BigQuery :

  • Firebase exporte vos données vers BigQuery. Notez que la propagation initiale des données pour l'exportation peut prendre jusqu'à 48 heures.

  • Firebase configure des synchronisations régulières de vos données de votre projet Firebase vers BigQuery. Ces opérations d'exportation quotidiennes commencent à 4 h 00 HAP et peuvent prendre jusqu'à dix heures.

  • Par défaut, toutes les applications de votre projet sont liées à BigQuery et toutes les applications que vous ajoutez ultérieurement au projet sont automatiquement liées à BigQuery. Vous pouvez gérer des applications qui envoient des données .

Pour désactiver l' exportation BigQuery, unlink votre projet dans la console Firebase.

Activer l'exportation des données de livraison des messages

Les appareils iOS avec le SDK FCM 8.6.0 ou une version ultérieure peuvent activer l'exportation des données de livraison des messages de leur application. FCM prend en charge l'exportation de données pour les notifications d'alerte et d'arrière-plan. Avant d' activer ces options, vous devez d' abord créer le lien FCM-BiqQuery pour votre projet tel que décrit dans l' exportation de données BigQuery .

Activer l'exportation des données de livraison pour les notifications d'alerte

Étant donné que seules les notifications d'alerte peuvent déclencher des extensions d'application de service de notification, vous devez ajouter une extension de service de notification à votre application et appeler cette API dans une extension de service pour activer le suivi des messages d'affichage. Consultez la documentation d'Apple sur le contenu Modification dans les notifications nouvellement livrés .

L'appel suivant doit être effectué pour chaque notification reçue :

Rapide

// For alert notifications, call the API inside the service extension:
class NotificationService: UNNotificationServiceExtension {
  override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
  Messaging.extensionHelper()
      .exportDeliveryMetricsToBigQuery(withMessageInfo:request.content.userInfo)
  }
}

Objectif c

// For alert notifications, call the API inside the service extension:
@implementation NotificationService
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request
                   withContentHandler:(void (^)(UNNotificationContent *_Nonnull))contentHandler {
  [[FIRMessaging extensionHelper] exportDeliveryMetricsToBigQueryWithMessageInfo:request.content.userInfo];
}
@end

Si vous créez les demandes envoyées en utilisant l'API HTTP v1, assurez - vous de spécifier mutable-content = 1 dans l' objet de la charge utile .

Activer l'exportation des données de livraison pour les notifications en arrière-plan

Pour les messages d'information reçus lorsque l'application est au premier plan ou arrière - plan, vous pouvez appeler l'API d'exportation de données dans le message de données de l' application principale gestionnaire UIApplicationDelegate application:didReceiveRemoteNotification:fetchCompletionHandler: l' UIApplicationDelegate application:didReceiveRemoteNotification:fetchCompletionHandler: . Cet appel doit être effectué pour chaque notification reçue :

Rapide

// For background notifications, call the API inside the UIApplicationDelegate method:
  func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) {
    Messaging.extensionHelper().exportDeliveryMetricsToBigQuery(withMessageInfo:userInfo)
  }

Objectif c

// For background notifications, call the API inside the UIApplicationDelegate method:
@implementation AppDelegate
- (void)application:(UIApplication *)application
    didReceiveRemoteNotification:(NSDictionary *)userInfo
          fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
  [[FIRMessaging extensionHelper] exportDeliveryMetricsToBigQueryWithMessageInfo:userInfo];
@end

Quelles données sont exportées vers BigQuery ?

Notez que le ciblage de jetons périmés ou d'enregistrements inactifs peut gonfler certaines de ces statistiques.

Le schéma de la table exportée est :

_PARTITIONTIME horodatage Cette pseudo-colonne contient un horodatage pour le début de la journée (en UTC) dans laquelle les données ont été chargées. Pour la partition AAAAMMJJ, cette pseudo-colonne contient la valeur TIMESTAMP('AAAA-MM-JJ').
event_timestamp horodatage Horodatage de l'événement tel qu'enregistré par le serveur
numéro de projet ENTIER Le numéro de projet identifie le projet qui a envoyé le message
ID du message CHAÎNE DE CARACTÈRES L'ID de message identifie un message. Généré à partir de l'ID d'application et de l'horodatage, l'ID de message peut, dans certains cas, ne pas être globalement unique.
instance_id CHAÎNE DE CARACTÈRES L'ID d'instance de l'application à laquelle le message est envoyé (si disponible)
type de message CHAÎNE DE CARACTÈRES Le type de message. Peut être un message de notification ou un message de données. Le sujet est utilisé pour identifier le message d'origine d'un sujet ou d'une campagne à envoyer ; les messages suivants sont soit une notification, soit un message de données.
sdk_platform CHAÎNE DE CARACTÈRES La plate-forme de l'application destinataire
nom de l'application CHAÎNE DE CARACTÈRES Le nom du package pour les applications Android ou l'identifiant du bundle pour les applications iOS
collapse_key CHAÎNE DE CARACTÈRES La clé de réduction identifie un groupe de messages qui peuvent être réduits. Lorsqu'un appareil n'est pas connecté, seul le dernier message avec une clé de réduction donnée est mis en file d'attente pour une livraison éventuelle
priorité ENTIER La priorité du message. Les valeurs valides sont "normal" et "élevé". Sur iOS, ceux-ci correspondent aux priorités APN 5 et 10
ttl ENTIER Ce paramètre spécifie combien de temps (en secondes) le message doit être conservé dans le stockage FCM si l'appareil est hors ligne
sujet CHAÎNE DE CARACTÈRES Le nom du sujet auquel un message a été envoyé (le cas échéant)
id_bulk ENTIER L'ID de masse identifie un groupe de messages associés, tel qu'un envoi particulier à un sujet
un événement CHAÎNE DE CARACTÈRES Le type de l'événement. Les valeurs possibles sont :
  • MESSAGE_ACCEPTED : le message a été reçu par le serveur FCM et la requête est valide ;
  • MESSAGE_DELIVERED : le message a été remis au SDK FCM de l'application sur l'appareil. Par défaut, ce champ n'est pas propagé. Pour activer, suivez les instructions fournies dans setDeliveryMetricsExportToBigQuery(boolean) .
  • MISSING_REGISTRATIONS : la demande a été rejetée en raison d'un enregistrement manquant ;
  • UNAUTHORIZED_REGISTRATION : le message a été rejeté car l'expéditeur n'est pas autorisé à envoyer à l'enregistrement ;
  • MESSAGE_RECEIVED_INTERNAL_ERROR : il y a eu une erreur non spécifiée lors du traitement de la demande de message ;
  • MISMATCH_SENDER_ID : la demande d'envoi d'un message a été rejetée en raison d'une incompatibilité entre l'identifiant de l'expéditeur envoyant le message et celui déclaré pour le point de terminaison ;
  • QUOTA_EXCEEDED : la demande d'envoi de message a été rejetée en raison d'un quota insuffisant ;
  • INVALID_REGISTRATION : la demande d'envoi de message a été rejetée en raison d'un enregistrement invalide ;
  • INVALID_PACKAGE_NAME : la demande d'envoi de message a été rejetée en raison d'un nom de package invalide ;
  • INVALID_APNS_CREDENTIAL : la demande d'envoi de message a été rejetée en raison d'un certificat APNS invalide ;
  • INVALID_PARAMETERS : la demande d'envoi de message a été rejetée en raison de paramètres invalides ;
  • PAYLOAD_TOO_LARGE : la demande d'envoi de message a été rejetée en raison d'une charge utile supérieure à la limite ;
  • AUTHENTICATION_ERROR : la demande d'envoi de message a été rejetée en raison d'une erreur d'authentification (vérifier la clé API utilisée pour envoyer le message) ;
  • INVALID_TTL : la demande d'envoi de message a été rejetée en raison d'un TTL invalide.
étiquette_analytique CHAÎNE DE CARACTÈRES Avec l' API HTTP v1 , l'étiquette d'analyse peut être réglée lors de l' envoi du message, afin de marquer le message à des fins d'analyse

Que pouvez-vous faire avec les données exportées ?

Les sections suivantes proposent des exemples de requêtes que vous pouvez exécuter dans BigQuery sur vos données FCM exportées.

Compter les messages envoyés par application

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;

Compter les instances d'application uniques ciblées par les messages

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

Compter les messages de notification envoyés

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';

Compter les messages de données envoyés

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';

Compter les messages envoyés à un sujet ou à une campagne

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 != '';

Pour suivre les événements pour un message envoyé au sujet particulier, modifier cette requête pour remplacer AND message_id != '' Avec AND message_id = <your message id>; .

Calculer la durée de diffusion pour un sujet ou une campagne donné

L'heure de début du déploiement correspond au moment où la demande d'origine est reçue et l'heure de fin est l'heure à laquelle le dernier message individuel ciblant une seule instance est créé.

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;

Compter le pourcentage de messages livrés

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;

Suivre tous les événements pour un identifiant de message et un identifiant d'instance donnés

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;

Calculer la latence pour un identifiant de message et un identifiant d'instance donnés

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;