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

Понимание доставки сообщений

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

  • Отчеты о доставке сообщений консоли Firebase и анализ воронки уведомлений
  • Агрегированные показатели доставки Android SDK из API данных Firebase Cloud Messaging.
  • Комплексный экспорт данных в Google BigQuery

Для работы всех инструментов отчетности, описанных на этой странице, требуется Google Analytics. Если Google Analytics не включен для вашего проекта, вы можете установить его в интеграций вкладке настроек проекта Firebase.

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

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

В Reports вкладке в консоли Firebase, вы можете просмотреть следующие данные для сообщений , отправленных Android или IOS ТСМ SDKs, в том числе посланного через композитор Notifications и API , ТСМ:

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

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

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

  • Платформа (iOS или Android)
  • Приложение
  • Пользовательские ярлыки аналитики

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

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

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

  • -
  • ~
  • %

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

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

Анализ воронки уведомлений

Встроенный анализ воронки уведомлений показывает, как ваши пользователи реагируют на определенные уведомления, отправленные из консоли Firebase. Это представление включает данные для целевых устройств iOS и Android в следующих категориях:

  • Уведомления отправлены - сообщение было поставлено в очередь для доставки или было успешно передано сторонней службе, такой как APN, для доставки. Обратите внимание, что таргетинг на устаревшие токены или неактивные регистрации может привести к завышению этой статистики.
  • Открытые уведомления - количество открытых уведомлений. Сообщается только для уведомлений, полученных, когда приложение работает в фоновом режиме.
  • Количество уникальных пользователей, инициировавших событие конверсии, если оно определено.

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

  1. В композитору Notifications, выберите Уведомления вкладку.
  2. Щелкните завершенное или текущее сообщение в списке сообщений. Отображается расширенное представление, включая анализ последовательности.

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

Агрегированные данные о доставке через API данных FCM

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

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

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

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

 {
  "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 поля может свидетельствовать о том , что экземпляры приложения получают объемы нескладных сообщений превышающих предел ТСМ по 100 ожидающих сообщений. Чтобы смягчить это, убедитесь , что ваши приложение обрабатывает вызовы к onDeletedMessages , и рассмотреть вопрос о направлении разборных сообщений. Кроме того , высокие проценты для droppedDeviceInactive могут быть сигналом для регистрации обновления маркеров на сервере, удаляя устаревшие маркера и отписку их от темы. См Управление ТСМ регистрации маркеров для наилучшей практики в этой области.

Процент эффективности доставки

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

Сообщение Insight Percentagess

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

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

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

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

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

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

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

Задержка данных

Данные, возвращаемые этим API, будут задерживаться до 5 дней. Например, 10 января будут доступны данные за 5 января, но не за 6 января или позже. Кроме того, данные предоставляются в максимально возможной степени. В случае сбоя данных FCM будет работать над исправлением ошибок и не будет заполнять данные заново после устранения проблемы. В случае более крупных отключений данные могут быть недоступны в течение недели или более.

Покрытие данных

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

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

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

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

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

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

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

Округление и минимумы

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

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

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

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

  • Android 20.1.0 или выше.
  • iOS 8.6.0 или выше
  • Firebase Web SDK 9.0.0 или выше

Ниже сведения о включении экспорта данных для Android и прошивкой .

Для начала свяжите свой проект с BigQuery:

  1. Выберите один из следующих вариантов:

    • Открой композитор Уведомления , а затем нажмите кнопку Access BigQuery в нижней части страницы.

    • Из интеграций страницы в Firebase консоли, нажмите Ссылку на карте BigQuery.

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

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

Обратитесь к Link Firebase к BigQuery для получения дополнительной информации.

После того, как вы свяжете свой проект с BigQuery:

  • Firebase экспортирует данные в BigQuery. Обратите внимание, что первоначальное распространение данных для экспорта может занять до 48 часов.

  • Firebase настраивает регулярную синхронизацию ваших данных из проекта Firebase с BigQuery. Эти ежедневные экспортные операции начинаются в 4:00 утра по тихоокеанскому времени и могут занять до десяти часов.

  • По умолчанию все приложения в вашем проекте связаны с BigQuery, а любые приложения, которые вы позже добавляете в проект, автоматически связываются с BigQuery. Вы можете управлять , какие приложения передачи данных .

Чтобы отключить экспорт BigQuery, разъединить ваш проект в консоли Firebase.

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

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

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

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

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

Быстрый

// 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)
  }
}

Цель-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 экспорта данных внутри сообщений данных обработчик главного приложения UIApplicationDelegate application:didReceiveRemoteNotification:fetchCompletionHandler: . Этот вызов должен выполняться для каждого полученного уведомления:

Быстрый

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

Цель-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

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

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

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

_PARTITIONTIME TIMESTAMP Этот псевдостолбец содержит метку времени начала дня (в формате UTC), в который были загружены данные. Для раздела ГГГГММДД этот псевдостолбец содержит значение TIMESTAMP ('ГГГГ-ММ-ДД').
event_timestamp TIMESTAMP Отметка времени события, записанная сервером
номер проекта ЦЕЛОЕ Номер проекта определяет проект, отправивший сообщение.
message_id НИТЬ Идентификатор сообщения идентифицирует сообщение. Созданный из идентификатора приложения и отметки времени, идентификатор сообщения в некоторых случаях может не быть уникальным в глобальном масштабе.
instance_id НИТЬ Идентификатор экземпляра приложения, которому отправлено сообщение (если доступно)
message_type НИТЬ Тип сообщения. Может быть уведомлением или сообщением с данными. Тема используется для идентификации исходного сообщения для темы или рассылки кампании; последующие сообщения являются либо уведомлением, либо сообщением с данными.
sdk_platform НИТЬ Платформа приложения-получателя
Название приложения НИТЬ Имя пакета для приложений Android или идентификатор пакета для приложений iOS.
collapse_key НИТЬ Ключ свертывания определяет группу сообщений, которые можно свернуть. Когда устройство не подключено, только последнее сообщение с заданным ключом сворачивания ставится в очередь для возможной доставки.
приоритет ЦЕЛОЕ Приоритет сообщения. Допустимые значения: «нормальный» и «высокий». В iOS они соответствуют приоритетам APN 5 и 10.
ttl ЦЕЛОЕ Этот параметр указывает, как долго (в секундах) сообщение должно храниться в хранилище FCM, если устройство отключено.
тема НИТЬ Название темы, в которую было отправлено сообщение (если применимо)
bulk_id ЦЕЛОЕ Идентификатор пакета идентифицирует группу связанных сообщений, например, конкретную отправку в тему.
мероприятие НИТЬ Тип мероприятия. Возможные значения:
  • 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 НИТЬ С 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;