Memahami pengiriman pesan

FCM menyediakan tiga rangkaian alat untuk membantu Anda mendapatkan insight tentang pengiriman pesan:

  • Laporan pengiriman pesan Firebase console
  • Gabungan metrik pengiriman Android SDK dari Firebase Cloud Messaging Data API
  • Ekspor data komprehensif ke Google BigQuery

Alat pelaporan yang dijelaskan di halaman ini memerlukan Google Analytics agar berfungsi. Jika Google Analytics tidak diaktifkan untuk project Anda, Anda dapat menyiapkannya di tab integrations pada setelan project Firebase Anda.

Perhatikan bahwa pelaporan banyak statistik di halaman ini berpotensi mengalami penundaan hingga 24 jam karena pengelompokan data analisis dalam batch.

Laporan pengiriman pesan

Di tab Reports di Firebase console, Anda dapat melihat data berikut untuk pesan yang dikirim ke FCM SDK platform Android atau Apple, termasuk yang dikirim melalui Notifications composer dan FCM API:

  • Sends — Pesan data atau pesan notifikasi telah masuk antrean pengiriman atau telah berhasil diteruskan ke layanan pihak ketiga seperti APNs untuk dikirimkan. Lihat masa aktif pesan untuk informasi lebih lanjut.
  • Received (hanya tersedia di perangkat Android) - Pesan data atau pesan notifikasi telah diterima oleh aplikasi. Data ini tersedia saat perangkat Android penerima memiliki FCM SDK 18.0.1 atau versi yang lebih baru.
  • Impressions (hanya tersedia untuk pesan notifikasi di perangkat Android) — Notifikasi tampilan telah ditampilkan di perangkat saat aplikasi berada di latar belakang.
  • Opens — Pengguna telah membuka pesan notifikasi. Dilaporkan hanya untuk notifikasi yang diterima ketika aplikasi berada di latar belakang.

Data ini tersedia untuk semua pesan dengan payload notifikasi dan semua pesan data berlabel. Untuk mempelajari label lebih lanjut, baca bagian Menambahkan label analisis ke pesan.

Saat melihat laporan pesan, Anda dapat menetapkan rentang tanggal untuk data yang ditampilkan, dengan opsi untuk mengekspornya ke CSV. Anda juga dapat melakukan pemfilteran berdasarkan kriteria berikut:

  • Platform (iOS atau Android)
  • Aplikasi
  • Label analisis kustom

Menambahkan label analisis ke pesan

Memberi label pada pesan sangat berguna untuk analisis kustom, sehingga Anda dapat memfilter statistik pengiriman berdasarkan label atau sekumpulan label. Anda dapat menambahkan label ke pesan yang dikirim melalui HTTP v1 API dengan menetapkan kolom fcmOptions.analyticsLabel di objek pesan, atau di kolom AndroidFcmOptions atau ApnsFcmOptions khusus platform.

Label analisis adalah string teks dalam format ^[a-zA-Z0-9-_.~%]{1,50}$. Label dapat meliputi huruf besar dan kecil, angka, serta simbol berikut:

  • -
  • ~
  • %

Panjang maksimal adalah 50 karakter. Anda dapat menentukan hingga 100 label unik per hari. Pesan dengan label yang ditambahkan di luar batas tersebut tidak akan dilaporkan.

Di tab Reports pengiriman pesan di Firebase console, Anda dapat menelusuri daftar semua label yang ada dan menerapkannya sendiri-sendiri atau bersama-sama untuk memfilter statistik yang ditampilkan.

Gabungan data pengiriman melalui FCM Data API

Dengan Firebase Cloud Messaging Data API, Anda dapat mengambil informasi yang dapat membantu Anda memahami hasil permintaan pesan yang ditargetkan ke aplikasi Android. API ini menyediakan data gabungan lintas perangkat Android yang mendukung pengumpulan data dalam sebuah project. Data ini mencakup detail tentang persentase pesan yang dikirim tanpa penundaan serta berapa banyak pesan yang tertunda atau dihapus dalam Android Transport Layer. Evaluasi data ini dapat mengungkap tren pengiriman pesan secara garis besar, dan membantu Anda menemukan cara yang efektif untuk meningkatkan performa permintaan pengiriman. Lihat Linimasa data gabungan untuk mengetahui informasi tentang ketersediaan rentang tanggal dalam laporan.

API ini menyediakan semua data yang tersedia untuk aplikasi tertentu. Baca dokumentasi referensi API.

Bagaimana cara pengelompokan data?

Data pengiriman dikelompokkan berdasarkan aplikasi, tanggal, dan label analisis. Panggilan ke API akan menampilkan data untuk setiap kombinasi tanggal, aplikasi, dan label analisis. Misalnya, objek JSON androidDeliveryData tunggal akan terlihat seperti ini:

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

Cara Menafsirkan Metrik

Data pengiriman menguraikan persentase pesan yang sesuai dengan setiap metrik berikut. Ada kemungkinan bahwa satu pesan sesuai dengan beberapa metrik. Karena keterbatasan kami dalam pengumpulan data dan tingkat perincian penggabungan metrik, beberapa hasil pesan sama sekali tidak diwakili dalam metrik, sehingga persentase di bawah tidak akan berjumlah 100%.

Jumlah Pesan yang Diterima

Satu-satunya jumlah yang disertakan dalam set data adalah jumlah pesan yang diterima oleh FCM untuk dikirim ke perangkat Android. Semua persentase menggunakan nilai ini sebagai penyebut. Perlu diingat bahwa jumlah ini tidak termasuk pesan yang ditargetkan ke pengguna yang telah menonaktifkan pengumpulan informasi penggunaan dan diagnostik di perangkatnya.

Persentase Hasil Pesan

Kolom yang disertakan dalam objek MessageOutcomePercents memberikan informasi tentang hasil permintaan pesan. Kategori-kategorinya tidak saling berhubungan. Objek ini dapat menjawab pertanyaan seperti "Apakah pesan saya dikirim?" dan "Apa yang menyebabkan pesan dihapus?"

Misalnya, nilai tinggi untuk kolom droppedTooManyPendingMessages dapat menandakan bahwa instance aplikasi menerima volume pesan yang tidak dapat diciutkan yang melebihi batas FCM, yaitu 100 pesan tertunda. Untuk mengurangi hal ini, pastikan aplikasi Anda menangani panggilan ke onDeletedMessages, dan pertimbangkan untuk mengirim pesan yang dapat diciutkan. Demikian pula, persentase tinggi untuk droppedDeviceInactive dapat menandakan bahwa token pendaftaran di server Anda perlu diperbarui, sehingga menghapus token yang sudah tidak relevan dan menghentikan langganan topiknya. Lihat Mengelola token pendaftaran FCM untuk mengetahui praktik terbaik di area ini.

Persentase Performa Pengiriman

Kolom dalam objek DeliveryPerformancePercents memberikan informasi tentang pesan yang berhasil dikirim. Alat ini dapat menjawab pertanyaan seperti "Apakah pesan saya tertunda?" dan "Mengapa pesan tertunda?" Misalnya, nilai tinggi untuk delayedMessageThrottled akan menunjukkan dengan jelas bahwa Anda melebihi batas maksimum per perangkat, dan harus menyesuaikan kecepatan pengiriman pesan.

Persentase Insight Pesan

Objek ini memberikan informasi tambahan tentang semua pengiriman pesan. Kolom priorityLowered menunjukkan persentase pesan yang diterima dengan prioritas yang diturunkan dari HIGH menjadi NORMAL. Jika nilai ini tinggi, coba kirim lebih sedikit pesan berprioritas tinggi atau pastikan Anda selalu menampilkan notifikasi saat pesan berprioritas tinggi dikirim. Lihat dokumentasi kami tentang prioritas pesan untuk informasi selengkapnya

Apa perbedaan data ini dengan data yang diekspor ke BigQuery?

Ekspor BigQuery menyediakan log pesan individual tentang penerimaan pesan oleh backend FCM dan pengiriman pesan di SDK pada perangkat (Langkah 2 dan 4 pada Arsitektur FCM). Data ini berguna untuk memastikan setiap pesan diterima dan terkirim. Baca selengkapnya tentang ekspor data BigQuery di bagian berikutnya.

Sebaliknya, Firebase Cloud Messaging Data API menyediakan detail gabungan tentang apa yang terjadi secara khusus di Android Transport Layer (atau Langkah 3 pada Arsitektur FCM). Data ini secara khusus memberikan insight tentang pengiriman pesan dari backend FCM ke Android SDK. Hal ini sangat berguna untuk menampilkan tren terkait alasan pesan tertunda atau dihapus selama pengiriman ini.

Dalam beberapa kasus, dua set data tersebut mungkin tidak sama persis karena hal berikut:

  • Metrik gabungan hanya mengambil sampel sebagian pesan
  • Metrik gabungan dibulatkan
  • Kami tidak menampilkan metrik di bawah nilai minimum privasi
  • Sebagian hasil pesan tidak akan ditampilkan karena alasan pengoptimalan dalam cara kami mengelola volume traffic yang besar.

Keterbatasan API

Linimasa Data Gabungan

API akan menampilkan data historis 7 hari; namun, data yang ditampilkan oleh API ini akan tertunda hingga 5 hari. Misalnya, pada 20 Januari, data untuk tanggal 9-15 Januari akan tersedia, tetapi tidak untuk tanggal 16 Januari atau setelahnya. Selain itu, data disediakan berdasarkan upaya terbaik. Jika terjadi gangguan data, FCM akan berupaya memperbaikinya dan tidak akan mengisi ulang data setelah masalah diperbaiki. Untuk gangguan yang lebih besar, data mungkin tidak tersedia selama seminggu atau lebih.

Cakupan Data

Metrik yang disediakan oleh Firebase Cloud Messaging Data API dimaksudkan untuk memberikan insight tentang tren pengiriman pesan secara garis besar. Namun, metrik tersebut tidak memberikan cakupan 100% untuk semua skenario pesan. Skenario berikut adalah hasil yang diketahui yang tidak ditunjukkan dalam metrik.

Pesan yang Diciutkan

Pesan yang telah diciutkan oleh pesan lain tidak muncul dalam set data.

Pesan ke perangkat yang tidak aktif

Pesan yang dikirim ke perangkat yang tidak aktif mungkin muncul atau tidak muncul dalam set data, bergantung pada jalur data yang digunakan. Hal ini dapat menyebabkan salah hitung di kolom droppedDeviceInactive dan pending.

Pesan ke perangkat dengan preferensi pengguna tertentu

Pesan untuk pengguna yang telah menonaktifkan pengumpulan informasi penggunaan dan diagnostik di perangkatnya tidak akan disertakan dalam penghitungan kami, sesuai dengan preferensinya.

Pembulatan dan Versi Minimum

FCM sengaja membulatkan dan mengecualikan jumlah jika volumenya tidak cukup besar.

Ekspor data BigQuery

Anda dapat mengekspor data pesan ke BigQuery untuk dianalisis lebih lanjut. Dengan BigQuery, Anda dapat menganalisis data menggunakan BigQuery SQL, mengekspornya ke penyedia cloud lain, atau menggunakan data tersebut untuk model ML kustom Anda. Ekspor ke BigQuery mencakup semua data yang tersedia untuk pesan, terlepas dari jenis pesan atau apakah pesan dikirim melalui API atau Notifications Composer.

Untuk pesan yang dikirim ke perangkat dengan versi minimum FCM SDK berikut, Anda memiliki opsi tambahan untuk mengaktifkan ekspor data pengiriman pesan untuk aplikasi Anda:

  • Android 20.1.0 atau yang lebih tinggi.
  • iOS 8.6.0 atau yang lebih tinggi
  • Firebase Web SDK 9.0.0 atau yang lebih tinggi

Lihat di bawah untuk mengetahui detail cara mengaktifkan ekspor data untuk Android dan iOS.

Untuk memulai, tautkan project Anda ke BigQuery:

  1. Pilih salah satu opsi berikut:

    • Buka Notifications Composer, lalu klik Access BigQuery di bagian bawah halaman.

    • Dari halaman Integrations di Firebase console, klik Link di kartu BigQuery.

      Halaman ini menampilkan opsi ekspor FCM untuk semua aplikasi yang dilengkapi FCM dalam project.

  2. Ikuti petunjuk di layar untuk mengaktifkan BigQuery.

Baca bagian Menautkan Firebase ke BigQuery untuk mendapatkan informasi lebih lanjut.

Saat Anda mengaktifkan BigQuery Export untuk Cloud Messaging:

  • Firebase akan mengekspor data Anda ke BigQuery. Perhatikan bahwa proses penerapan data awal untuk ekspor mungkin memakan waktu hingga 48 jam.

  • Setelah set data dibuat, lokasi tidak dapat diubah, tetapi Anda dapat menyalin set data ke lokasi lain atau memindahkan (membuat ulang) set data secara manual di lokasi yang berbeda. Untuk mempelajari lebih lanjut, baca artikel Mengubah lokasi set data.

  • Firebase akan menyiapkan sinkronisasi reguler data Anda dari project Firebase ke BigQuery. Operasi ekspor harian ini dimulai pada pukul 04.00 Waktu Pasifik dan biasanya selesai dalam waktu 24 jam.

  • Secara default, semua aplikasi di project Anda akan ditautkan ke BigQuery, dan semua aplikasi yang Anda tambahkan nanti ke project akan otomatis ditautkan ke BigQuery. Anda dapat mengelola aplikasi yang akan mengirimkan data.

Untuk menonaktifkan BigQuery Export, batalkan tautan project Anda di Firebase console.

Mengaktifkan ekspor data pengiriman pesan

Perangkat iOS dengan FCM SDK 8.6.0 atau lebih tinggi dapat mengaktifkan ekspor data pengiriman pesan untuk aplikasinya. FCM mendukung ekspor data untuk notifikasi pemberitahuan dan latar belakang. Sebelum mengaktifkan opsi ini, Anda harus terlebih dahulu membuat link FCM-BiqQuery untuk project Anda seperti yang dijelaskan dalam artikel Ekspor data BigQuery.

Mengaktifkan ekspor data pengiriman untuk notifikasi pemberitahuan

Karena hanya notifikasi pemberitahuan yang dapat memicu ekstensi aplikasi layanan notifikasi, Anda harus menambahkan ekstensi layanan notifikasi ke aplikasi Anda dan memanggil API ini di dalam ekstensi layanan untuk mengaktifkan pelacakan pesan tampilan. Lihat dokumentasi Apple terkait Memodifikasi Konten di Notifikasi yang Baru Dikirimkan.

Panggilan berikut harus dilakukan untuk setiap notifikasi yang diterima:

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.extensionHelper()
      .exportDeliveryMetricsToBigQuery(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

Jika Anda mem-build permintaan kirim menggunakan HTTP v1 API, pastikan untuk menentukan mutable-content = 1 dalam objek payload.

Mengaktifkan ekspor data pengiriman untuk notifikasi latar belakang

Untuk pesan latar belakang yang diterima saat aplikasi berada di latar depan atau latar belakang, Anda dapat memanggil API ekspor data di dalam pengendali pesan data aplikasi utama. Panggilan ini harus dilakukan untuk setiap notifikasi yang diterima:

Swift

// For background notifications, call the API inside the UIApplicationDelegate or NSApplicationDelegate method:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) {
  Messaging.extensionHelper().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

Data apa yang diekspor ke BigQuery?

Perhatikan bahwa penargetan token yang sudah tidak berlaku atau pendaftaran yang tidak aktif dapat menyebabkan beberapa statistik ini menjadi lebih tinggi.

Skema tabel yang diekspor adalah:

_PARTITIONTIME TIMESTAMP Kolom semu ini memiliki stempel waktu untuk menunjukkan jam saat data mulai dimuat (dalam UTC). Untuk partisi YYYYMMDD, kolom semu ini berisi nilai TIMESTAMP('YYYY-MM-DD').
event_timestamp TIMESTAMP Stempel waktu peristiwa seperti yang dicatat oleh server
project_number INTEGER Nomor project mengidentifikasi project yang mengirim pesan
message_id STRING ID pesan mengidentifikasi pesan. Dalam beberapa kasus, ID pesan yang dibuat dari ID Aplikasi dan stempel waktu mungkin bukanlah ID unik global (GUID).
instance_id STRING ID unik aplikasi penerima pesan (jika tersedia). ID unik ini bisa berupa ID instance atau ID penginstalan Firebase.
message_type STRING Jenis pesan. Dapat berupa pesan Notification atau pesan Data. Topik digunakan untuk mengidentifikasi pesan asli yang dikirim ke topik atau kampanye; pesan berikutnya berupa pesan notifikasi atau data.
sdk_platform STRING Platform aplikasi penerima
app_name STRING Nama paket untuk aplikasi Android atau ID paket untuk aplikasi iOS
collapse_key STRING Kunci penciutan mengidentifikasi sekelompok pesan yang dapat diciutkan. Ketika perangkat tidak terhubung, hanya pesan terakhir dengan kunci penciutan tertentu yang dimasukkan antrean untuk akhirnya dikirim
priority INTEGER Prioritas pesan. Nilai yang valid adalah "normal" dan "high". Di iOS, ini sama dengan prioritas APN 5 dan 10
ttl INTEGER Parameter ini menetapkan berapa lama (dalam detik) pesan harus disimpan dalam penyimpanan FCM jika perangkat sedang offline
topic STRING Nama topik penerima pesan (jika ada)
bulk_id INTEGER ID massal mengidentifikasi sekelompok pesan terkait, seperti pengiriman tertentu ke suatu topik
event STRING Jenis peristiwa. Nilai yang mungkin adalah:
  • MESSAGE_ACCEPTED: pesan diterima oleh server FCM dan permintaan valid;
  • MESSAGE_DELIVERED: pesan telah dikirim ke FCM SDK aplikasi di perangkat. Secara default, kolom ini tidak diterapkan. Untuk mengaktifkannya, ikuti petunjuk di setDeliveryMetricsExportToBigQuery(boolean).
  • MISSING_REGISTRATIONS: permintaan ditolak karena pendaftaran tidak ada;
  • UNAUTHORIZED_REGISTRATION: pesan ditolak karena pengirim tidak memiliki otorisasi untuk mengirim ke pendaftaran;
  • MESSAGE_RECEIVED_INTERNAL_ERROR: terjadi error yang belum ditetapkan saat memproses permintaan pesan;
  • MISMATCH_SENDER_ID: permintaan untuk mengirim pesan ditolak karena ada ketidakcocokan antara ID pengirim yang mengirim pesan, dan ID pengirim yang dideklarasikan untuk endpoint;
  • QUOTA_EXCEEDED: permintaan untuk mengirim pesan ditolak karena kuota tidak mencukupi;
  • INVALID_REGISTRATION: permintaan untuk mengirim pesan ditolak karena pendaftaran tidak valid;
  • INVALID_PACKAGE_NAME: permintaan untuk mengirim pesan ditolak karena nama paket tidak valid;
  • INVALID_APNS_CREDENTIAL: permintaan untuk mengirim pesan ditolak karena sertifikat APNS tidak valid;
  • INVALID_PARAMETERS: permintaan untuk mengirim pesan ditolak karena parameter tidak valid;
  • PAYLOAD_TOO_LARGE: permintaan untuk mengirim pesan ditolak karena payload melampaui batas;
  • AUTHENTICATION_ERROR: permintaan untuk mengirim pesan ditolak karena terjadi error autentikasi (periksa Kunci API yang digunakan untuk mengirim pesan);
  • INVALID_TTL: permintaan untuk mengirim pesan ditolak karena TTL tidak valid.
analytics_label STRING Dengan HTTP v1 API, label analisis dapat ditetapkan saat mengirim pesan, guna menandai pesan untuk tujuan analisis

Apa yang dapat dilakukan dengan data hasil ekspor?

Bagian berikut memperlihatkan contoh kueri yang dapat dijalankan di BigQuery terhadap data yang diekspor dari FCM.

Menghitung pesan yang terkirim menurut aplikasi

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;

Menghitung instance aplikasi unik yang ditarget oleh pesan

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

Menghitung pesan notifikasi yang terkirim

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

Menghitung pesan data yang terkirim

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

Menghitung pesan yang dikirim ke topik atau kampanye

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

Guna melacak peristiwa untuk pesan yang dikirim ke topik tertentu, ubah kueri ini untuk mengganti AND message_id != '' dengan AND message_id = <your message id>;.

Menghitung durasi fanout untuk topik atau kampanye tertentu

Waktu mulai fanout adalah ketika permintaan aslinya diterima, dan waktu berakhirnya adalah ketika satu pesan terakhir yang menarget satu instance dibuat.

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;

Menghitung persentase pesan yang terkirim

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;

Melacak semua peristiwa untuk ID pesan dan ID instance tertentu

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;

Menghitung latensi untuk ID pesan dan ID instance tertentu

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;