Как доставляются сообщения

Чтобы устранить неполадки с доставкой сообщений, воспользуйтесь инструментом устранения неполадок FCM и прочитайте эту запись блога, в которой рассказывается о возможных причинах проблем. Вы также можете посетить панель мониторинга FCM, чтобы узнать, есть ли в настоящее время сбои в работе сервиса, влияющие на FCM.

FCM также предоставляет три набора инструментов, которые помогут вам получить представление о широкой оценке успеха и стратегии обмена сообщениями:

  • Firebase отчетов о доставке сообщений в консоли
  • Агрегированные показатели показа Android SDK из Firebase Cloud Messaging Data API
  • Экспорт всех данных в Google BigQuery

Экспорт данных в BigQuery и вкладка Отчеты в консоли Firebase работают только при наличии Google Analytics. Вы можете включить Google Analytics в консоли Firebase на вкладке Настройки > Интеграции. Для работы агрегированных данных о показе Google Analytics не требуется.

Обратите внимание, что многие статистические данные на этой странице обновляются с задержкой до 24 часов из-за пакетной обработки данных аналитики.

Отчеты о доставке сообщений

В консоли Firebase перейдите в раздел DevOps & Engagement (DevOps и вовлечение) > Messaging (Обмен сообщениями) > Reports (Отчеты), чтобы посмотреть следующие данные о сообщениях, отправленных в FCM SDK для платформ Android или Apple, в том числе с помощью компоновщика уведомлений и FCM API:

  • "Отправлено" – сообщение с данными или уведомление поставлено в очередь на доставку или успешно передано стороннему сервису, например APNs, для доставки. Обратите внимание, что статистика по отправленным письмам может обновляться с задержкой в несколько часов. Подробнее о сроке хранения сообщений…
  • "Получено" (доступно только на устройствах Android) – приложение получило сообщение с данными или уведомление. Эти данные доступны, если на принимающем устройстве Android установлен SDK FCM версии 18.0.1 или более поздней.
  • Показы (доступно только для уведомлений на устройствах Android) – уведомление было показано на устройстве, когда приложение работало в фоновом режиме.
  • Открытия – пользователь открыл уведомление. Регистрируется только для уведомлений, полученных, когда приложение работает в фоновом режиме.

Эти данные доступны для всех сообщений с полезной нагрузкой уведомления и всех помеченных сообщений с данными. Подробнее о добавлении ярлыков аналитики в сообщения…

При просмотре отчетов о сообщениях можно задать диапазон дат для отображаемых данных и экспортировать их в формате CSV. Вы также можете отфильтровать данные по следующим критериям:

  • Платформа (iOS или Android).
  • Приложение
  • Специальные ярлыки аналитики

Добавление ярлыков аналитики к сообщениям

Ярлыки очень полезны для анализа, поскольку позволяют фильтровать статистику доставки по ярлыкам или их наборам. Вы можете добавить ярлык к любому сообщению, отправленному с помощью HTTP v1 API, заполнив поле fcmOptions.analyticsLabel в объекте message или в полях AndroidFcmOptions или ApnsFcmOptions, относящихся к конкретной платформе.

Ярлыки Аналитики – это текстовые строки в формате ^[a-zA-Z0-9-_.~%]{1,50}$. Ярлыки могут содержать строчные и заглавные буквы, цифры и следующие символы:

  • -
  • ~
  • %

Максимальная длина – 50 символов. В день можно указать до 100 уникальных ярлыков. Сообщения с ярлыками, добавленными сверх этого лимита, не включаются в отчеты.

На вкладке Отчеты в разделе сообщений консоли Firebase можно найти список всех существующих ярлыков и применить их по отдельности или в сочетании, чтобы отфильтровать отображаемую статистику.

Агрегированные данные о показе, полученные с помощью FCM Data API

Firebase Cloud Messaging Data API позволяет получать информацию, которая помогает понять результаты запросов сообщений, предназначенных для приложений Android. API предоставляет агрегированные данные по всем устройствам Android в проекте, на которых включен сбор данных. В частности, вы можете узнать, какой процент сообщений был доставлен без задержек, а также сколько сообщений было задержано или отклонено на транспортном уровне Android. Анализ этих данных может выявить общие тенденции в доставке сообщений и помочь вам найти эффективные способы повышения производительности ваших запросов на отправку. Информацию о доступности диапазонов дат в отчетах можно найти в разделе Сроки агрегирования данных.

API предоставляет все данные, доступные для определенного приложения. Ознакомьтесь со справочной документацией по API.

Как разбиваются данные?

Данные о доставке разбиты по приложениям, датам и ярлыкам аналитики. Вызов API возвращает данные для каждого сочетания даты, приложения и ярлыка аналитики. Например, один объект JSON androidDeliveryData будет выглядеть следующим образом:

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

Как интерпретировать показатели

Данные о доставке показывают процент сообщений, соответствующих каждому из следующих показателей. Одно сообщение может соответствовать нескольким показателям. Из-за ограничений, связанных со сбором данных и уровнем детализации, на котором мы агрегируем показатели, некоторые результаты сообщений вообще не представлены в показателях, поэтому сумма процентов ниже не будет равна 100 %.

Количество принятых сообщений

В набор данных включается только количество сообщений, принятых FCM для доставки на устройства Android. Это значение используется в качестве знаменателя для всех процентных показателей. Обратите внимание, что в это число не входят сообщения, предназначенные для пользователей, которые отключили сбор данных об использовании и диагностике на своих устройствах.

Процент результатов сообщений

Поля, включенные в объект MessageOutcomePercents, содержат информацию о результатах запросов сообщений. Все категории являются взаимоисключающими. С его помощью можно получить ответы на такие вопросы, как "Доставляются ли мои сообщения?" и "Почему сообщения отклоняются?".

Например, высокое значение в поле droppedTooManyPendingMessages может означать, что экземпляры приложения получают несворачиваемые сообщения в количестве, превышающем лимит FCM в 100 ожидающих сообщений. Чтобы избежать этого, убедитесь, что ваше приложение обрабатывает вызовы onDeletedMessages, и рассмотрите возможность отправки сворачиваемых сообщений. Аналогично, высокий процент droppedDeviceInactive может быть сигналом к обновлению токенов регистрации на сервере, удалению устаревших токенов и отмене их подписки на темы. Ознакомьтесь с рекомендациями в статье Как управлять токенами регистрации FCM.

Процентные показатели эффективности доставки

Поля в объекте DeliveryPerformancePercents содержат информацию об успешно доставленных сообщениях. С его помощью можно получить ответы на такие вопросы, как "Были ли задержки в доставке моих писем?" и "Почему письма задерживаются?". Например, высокое значение delayedMessageThrottled явно указывает на то, что вы превышаете максимальные ограничения для одного устройства и вам следует скорректировать частоту отправки сообщений.

Процентные показатели в статистике сообщений

Этот объект предоставляет дополнительную информацию обо всех отправленных сообщениях. Поле priorityLowered содержит процент принятых сообщений, приоритет которых был снижен с HIGH до NORMAL. Если это значение высокое, попробуйте отправлять меньше сообщений с высоким приоритетом или убедитесь, что при отправке сообщения с высоким приоритетом всегда показывается уведомление. Подробную информацию можно найти в документации о приоритете сообщений.

Чем эти данные отличаются от данных, экспортированных в BigQuery?

Экспорт BigQuery предоставляет отдельные журналы сообщений о принятии сообщений серверной частью FCM и доставке сообщений в SDK на устройстве (шаги 2 и 4 архитектуры FCM). Эти данные позволяют убедиться, что отдельные сообщения были приняты и доставлены. Подробнее об экспорте данных в BigQuery…

В отличие от него, Firebase Cloud Messaging Data API предоставляет агрегированные сведения о том, что происходит на транспортном уровне Android (шаг 3 в архитектуре FCM). Эти данные позволяют понять, как сообщения доставляются из бэкендов FCM в Android SDK. Это особенно полезно для выявления тенденций, объясняющих, почему письма задерживались или отклонялись во время передачи.

В некоторых случаях эти два набора данных могут не совпадать по следующим причинам:

  • Агрегированные показатели рассчитываются только на основе части всех сообщений.
  • Агрегированные показатели округляются.
  • Мы не показываем показатели, которые не соответствуют пороговому значению конфиденциальности.
  • Часть результатов сообщений отсутствует из-за оптимизации управления большим объемом трафика.

Ограничения API

Сроки агрегирования данных

API возвращает статистику за семь дней, но с задержкой до пяти дней. Например, 20 января будут доступны данные за период с 9 по 15 января, но не за 16 января или более поздние даты. Кроме того, данные предоставляются по мере возможности. В случае сбоя в работе FCM мы постараемся устранить его как можно скорее, но не будем восстанавливать данные за период сбоя. При более серьезных сбоях данные могут быть недоступны в течение недели или дольше.

Охват данных

Показатели, предоставляемые Firebase Cloud Messaging Data API, позволяют выявлять общие тенденции в доставке сообщений. Однако они не охватывают все возможные сценарии. Ниже перечислены известные результаты, которые не отражены в показателях.

Сообщения с истекшим сроком действия

Если время жизни (TTL) истекает после окончания указанной даты в журнале, сообщение не будет считаться droppedTtlExpired в эту дату.

Сообщения на неактивные устройства

Сообщения, отправленные на неактивные устройства, могут как появиться, так и не появиться в наборе данных в зависимости от того, по какому пути они передаются. Это может привести к неточностям в полях droppedDeviceInactive и pending.

Сообщения для устройств с определенными пользовательскими настройками

Если пользователь отключил сбор данных об использовании и диагностике на своем устройстве, его сообщения не будут учитываться.

Округление и минимальные значения

FCM намеренно округляет и исключает подсчеты, когда объемы недостаточно велики.

Экспорт данных в BigQuery

Вы можете экспортировать данные о сообщениях в BigQuery для дальнейшего анализа. BigQuery позволяет анализировать данные с помощью BigQuery SQL, экспортировать их другому поставщику облачных сервисов или использовать для собственных моделей ML. Экспорт в BigQuery включает все доступные данные о сообщениях, независимо от их типа и от того, отправлены ли они с помощью API или Компоновщика уведомлений.

Для сообщений, отправленных на устройства с указанными ниже минимальными версиями SDK FCM, вы можете включить экспорт данных о доставке сообщений для вашего приложения:

  • Android 20.1.0 или более поздней версии.
  • iOS 8.6.0 или более поздней версии.
  • Firebase Web SDK версии 12.14.0 или более поздней.

Чтобы начать, свяжите проект с BigQuery в консоли Firebase.

  1. Выберите действие. Вы можете:

    • Перейдите в раздел DevOps & Engagement (DevOps и вовлечение) > Messaging (Обмен сообщениями) > the Notifications composer (Компоновщик уведомлений), а затем нажмите Access BigQuery (Доступ к BigQuery) внизу страницы.

    • Перейдите на вкладку Settings (Настройки) > Integrations (Интеграции). Затем в BigQuery нажмите Связать.

      На этой странице показаны варианты экспорта FCM для всех приложений проекта, в которых включен FCM.

  2. Следуйте инструкциям на экране, чтобы включить BigQuery.

Подробнее о том, как связать BigQuery с Firebase…

Если вы включите экспорт данных BigQuery для Cloud Messaging:

Чтобы отключить экспорт в BigQuery, отмените связь с проектом в консоли Firebase.

Как включить экспорт данных о доставке сообщений

iOS+

На устройствах iOS с SDK FCM 8.6.0 или более поздней версии можно включить экспорт данных о доставке сообщений приложения. FCM поддерживает экспорт данных как для оповещений, так и для фоновых уведомлений. По умолчанию экспорт данных отключен на уровне приложения. Если вы включите его программно на уровне экземпляра приложения, то сможете запрашивать у конечных пользователей разрешение на анализ данных о доставке сообщений (рекомендуется). Если заданы оба значения, то значение на уровне экземпляра приложения переопределяет значение на уровне приложения.

Прежде чем включить эти параметры, необходимо создать связь FCM-BigQuery для проекта, как описано в статье Экспорт данных в BigQuery.

Как включить экспорт данных о доставке для оповещений

Поскольку только уведомления могут активировать расширения приложений службы уведомлений, вам необходимо добавить расширение службы уведомлений в свое приложение и вызвать этот API внутри расширения службы, чтобы включить отслеживание отображаемых сообщений. Ознакомьтесь с документацией Apple по изменению контента в новых уведомлениях.

Для каждого полученного уведомления необходимо выполнить следующий вызов:

Swift

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

Objective-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

Если вы создаете запросы на отправку с помощью HTTP v1 API, укажите `mutable-content = 1` в объекте полезной нагрузки.

Включить экспорт данных о доставке для фоновых уведомлений

Для фоновых сообщений, полученных, когда приложение работает в активном или фоновом режиме, вы можете вызвать API экспорта данных в обработчике сообщений с данными основного приложения. Этот вызов необходимо выполнять для каждого полученного уведомления:

Swift

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

Objective-C

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

Android

На устройствах Android с FCM SDK версии 20.1.0 или более поздней можно включить экспорт данных о доставке сообщений в приложении. По умолчанию экспорт данных отключен на уровне приложения. Если вы включите его программно на уровне экземпляра приложения, то сможете запрашивать у конечных пользователей разрешение на анализ данных о доставке сообщений (рекомендуется). Если заданы оба значения, то значение на уровне экземпляра приложения переопределяет значение на уровне приложения.

Прежде чем включать эти параметры, необходимо создать связь FCM с BigQuery для проекта, как описано в разделе Экспорт данных в BigQuery.

Как включить экспорт данных о доставке для экземпляров приложения

В большинстве случаев мы рекомендуем включить экспорт данных о доставке сообщений только на уровне экземпляра приложения и оставить его отключенным на уровне приложения.

FirebaseMessaging.getInstance().setDeliveryMetricsExportToBigQuery(true);

Как включить экспорт данных о доставке для приложения

Если вы хотите включить экспорт на уровне приложения, не вызывайте метод setDeliveryMetricsExportToBigQuery и добавьте следующее свойство в объект приложения в манифесте приложения:

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

Веб-приложение

FCM SDK для веб-приложений версии 12.14.0 или более поздней позволяет экспортировать данные о показе. По умолчанию экспорт данных отключен на уровне приложения. Если вы включите его программно на уровне экземпляра приложения, то сможете запрашивать у конечных пользователей разрешение на анализ данных о доставке сообщений (рекомендуется). Если заданы оба значения, то значение на уровне экземпляра приложения переопределяет значение на уровне приложения. Когда конечный пользователь дает согласие на сбор данных или отказывается от него, приложение должно установить экспериментальный флаг включения или отключения для каждого экземпляра приложения, как показано ниже.

// userConsent holds the decision of the user to give big query export consent.
const userConsent = ...;

const messaging = getMessagingInSw(app);

experimentalSetDeliveryMetricsExportedToBigQueryEnabled(messaging, userConsent);

Какие данные экспортируются в BigQuery?

Обратите внимание, что таргетинг на устаревшие токены или неактивные регистрации может завышать некоторые из этих статистических данных.

Схема экспортированной таблицы:

_PARTITIONTIME ВРЕМЕННЫЕ МЕТКИ Этот псевдостолбец содержит временную метку начала дня (в формате UTC), в который были загружены данные. Для раздела ГГГГММДД этот псевдостолбец содержит значение TIMESTAMP('ГГГГ-ММ-ДД').
event_timestamp ВРЕМЕННЫЕ МЕТКИ Временная метка события, зарегистрированная сервером.
project_number INTEGER Номер проекта, из которого было отправлено сообщение.
message_id STRING Идентификатор сообщения позволяет определить сообщение. Идентификатор сообщения создается на основе идентификатора приложения и временной метки и в некоторых случаях может не быть уникальным.
instance_id STRING Уникальный идентификатор приложения, в которое отправлено сообщение (если доступен). Это может быть идентификатор экземпляра или идентификатор установки Firebase.
message_type STRING Тип сообщения. Это может быть уведомление или сообщение с данными. Тема используется для идентификации исходного сообщения для темы или отправки кампании. Последующие сообщения являются либо уведомлениями, либо сообщениями с данными.
sdk_platform STRING Платформа приложения-получателя.
app_name STRING Название пакета для приложений Android или идентификатор пакета для приложений iOS.
collapse_key STRING Ключ свертывания идентифицирует группу сообщений, которые можно свернуть. Если устройство не подключено, в очередь на доставку помещается только последнее сообщение с заданным ключом свертывания.
прием в приоритетном порядке INTEGER Приоритет сообщения. 5 – обычный приоритет, 10 – высокий.
ttl INTEGER Этот параметр определяет, как долго (в секундах) сообщение должно храниться в FCM, если устройство находится в офлайн-режиме.
тема STRING Название темы, в которую было отправлено сообщение (если применимо).
bulk_id INTEGER Идентификатор массовой рассылки позволяет определить группу связанных писем, например отправленных по определенной теме.
event STRING Тип события. Возможные значения:
  • MESSAGE_ACCEPTED: сообщение получено сервером FCM, запрос действителен.
  • MESSAGE_DELIVERED – сообщение доставлено в FCM SDK приложения на устройстве. По умолчанию это поле не распространяется. Чтобы включить его, следуйте инструкциям в setDeliveryMetricsExportToBigQuery(boolean).
  • MISSING_REGISTRATIONS – запрос отклонен из-за отсутствия регистрации;
  • UNAUTHORIZED_REGISTRATION – сообщение отклонено, поскольку отправитель не авторизован для отправки на регистрацию.
  • MESSAGE_RECEIVED_INTERNAL_ERROR – при обработке запроса сообщения произошла неизвестная ошибка.
  • MISMATCH_SENDER_ID – запрос на отправку сообщения отклонен из-за несоответствия между идентификатором отправителя, отправляющего сообщение, и идентификатором, объявленным для конечной точки.
  • QUOTA_EXCEEDED – запрос на отправку сообщения был отклонен из-за недостаточной квоты.
  • INVALID_REGISTRATION – запрос на отправку сообщения отклонен из-за недопустимой регистрации.
  • INVALID_PACKAGE_NAME: запрос на отправку сообщения был отклонен из-за недопустимого названия пакета.
  • INVALID_APNS_CREDENTIAL: запрос на отправку сообщения был отклонен из-за недействительного сертификата APNS.
  • INVALID_PARAMETERS: запрос на отправку сообщения был отклонен из-за недопустимых параметров.
  • PAYLOAD_TOO_LARGE – запрос на отправку сообщения отклонен, поскольку полезная нагрузка превышает лимит.
  • AUTHENTICATION_ERROR – запрос на отправку сообщения отклонен из-за ошибки аутентификации (проверьте ключ API, используемый для отправки сообщения);
  • INVALID_TTL: запрос на отправку сообщения отклонен из-за недопустимого значения TTL.
analytics_label STRING При использовании HTTP v1 API ярлык аналитики можно задать при отправке сообщения, чтобы пометить его для целей аналитики.

Что можно делать с экспортированными данными?

В следующих разделах приведены примеры запросов, которые можно выполнять в BigQuery с экспортированными данными FCM.

Количество отправленных сообщений по приложениям

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;

Подсчет уникальных экземпляров приложения, на которые настроен таргетинг сообщений

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

Количество отправленных уведомлений

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

Количество отправленных сообщений с данными

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

Как подсчитать количество сообщений, отправленных в рамках темы или кампании

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

Чтобы отслеживать события для сообщения, отправленного в определенную тему, измените этот запрос, заменив AND message_id != '' на AND message_id = <your message id>;.

Вычисление длительности развертывания для заданной темы или кампании

Время начала разветвления – это время получения исходного запроса, а время окончания – это время создания последнего отдельного сообщения, предназначенного для одного экземпляра.

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;

Процент доставленных писем

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;

Отслеживать все события для заданного идентификатора сообщения и идентификатора экземпляра

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;

Вычислить задержку для заданного идентификатора сообщения и идентификатора экземпляра

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;