Ikuti semua informasi yang diumumkan di Firebase Summit, dan pelajari bagaimana Firebase dapat membantu Anda mempercepat pengembangan aplikasi dan menjalankan aplikasi dengan percaya diri. Pelajari Lebih Lanjut

Memahami pengiriman pesan

Tetap teratur dengan koleksi Simpan dan kategorikan konten berdasarkan preferensi Anda.

FCM menyediakan tiga set alat untuk membantu Anda mendapatkan wawasan tentang pengiriman pesan:

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

Semua alat pelaporan yang dijelaskan di halaman ini memerlukan Google Analytics agar dapat berfungsi. Jika Google Analytics tidak diaktifkan untuk proyek Anda, Anda dapat menyiapkannya di tab integrasi pada pengaturan proyek Firebase Anda.

Perlu diingat bahwa pelaporan banyak statistik di halaman ini, dapat tertunda hingga 24 jam karena pengelompokan data analitik.

Laporan pengiriman pesan

Di tab Laporan di konsol Firebase, Anda dapat melihat data berikut untuk pesan yang dikirim ke SDK FCM platform Android atau Apple, termasuk yang dikirim melalui penulis Notifikasi dan API FCM:

  • Mengirim — Pesan data atau pesan pemberitahuan telah diantrekan untuk pengiriman atau telah berhasil diteruskan ke layanan pihak ketiga seperti APN untuk pengiriman. Lihat umur pesan untuk informasi lebih lanjut.
  • Diterima (hanya tersedia di perangkat Android) — Pesan data atau pesan notifikasi telah diterima oleh aplikasi. Data ini tersedia jika perangkat Android penerima telah menginstal FCM SDK 18.0.1 atau lebih tinggi.
  • Tayangan (hanya tersedia untuk pesan notifikasi di perangkat Android) — Notifikasi tampilan telah ditampilkan di perangkat saat aplikasi berada di latar belakang.
  • Terbuka — Pengguna membuka pesan notifikasi. Dilaporkan hanya untuk notifikasi yang diterima saat aplikasi berada di latar belakang.

Data ini tersedia untuk semua pesan dengan payload notifikasi dan semua pesan data berlabel . Untuk mempelajari lebih lanjut tentang label, lihat Menambahkan label analitik ke pesan .

Saat melihat laporan pesan, Anda dapat menetapkan rentang tanggal untuk data yang ditampilkan, dengan opsi untuk mengekspor ke CSV. Anda juga dapat memfilter menurut kriteria berikut:

  • Platform (iOS atau Android)
  • Aplikasi
  • Label analitik khusus

Menambahkan label analitik ke pesan

Pelabelan pesan sangat berguna untuk analisis khusus, memungkinkan Anda memfilter statistik pengiriman menurut label atau kumpulan label. Anda dapat menambahkan label ke pesan apa pun yang dikirim melalui HTTP v1 API dengan menyetel kolom fcmOptions.analyticsLabel di objek pesan , atau di kolom AndroidFcmOptions ApnsFcmOptions platform.

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

  • -
  • ~
  • %

Panjang maksimal adalah 50 karakter. Anda dapat menentukan hingga 100 label unik per hari; pesan dengan label yang ditambahkan melebihi batas tersebut tidak dilaporkan.

Di tab Laporan perpesanan konsol Firebase, Anda dapat menelusuri daftar semua label yang ada dan menerapkannya secara tunggal atau kombinasi untuk memfilter statistik yang ditampilkan.

Data pengiriman gabungan melalui FCM Data API

Firebase Cloud Messaging Data API memungkinkan Anda mengambil informasi yang dapat membantu Anda memahami hasil permintaan pesan yang ditargetkan ke aplikasi Android. API menyediakan data gabungan di semua perangkat Android yang mendukung pengumpulan data dalam sebuah proyek. Ini mencakup detail tentang persentase pesan yang dikirim tanpa penundaan serta berapa banyak pesan yang ditunda atau dihapus dalam Lapisan Transportasi Android . Mengevaluasi data ini dapat mengungkap tren luas dalam pengiriman pesan dan membantu Anda menemukan cara yang efektif untuk meningkatkan kinerja permintaan pengiriman Anda. Lihat Linimasa data gabungan untuk informasi tentang ketersediaan rentang tanggal di laporan.

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

Bagaimana data dipecah?

Data pengiriman dikelompokkan menurut aplikasi, tanggal, dan label analitik . Panggilan ke API akan mengembalikan data untuk setiap kombinasi tanggal, aplikasi, dan label analitik. Misalnya, satu objek JSON androidDeliveryData 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
    }
  }

Bagaimana Menafsirkan Metrik

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

Hitung Pesan Diterima

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

Persentase Hasil Pesan

Bidang yang termasuk dalam objek MessageOutcomePercents memberikan informasi tentang hasil permintaan pesan. Semua kategori saling eksklusif. Itu dapat menjawab pertanyaan seperti "Apakah pesan saya terkirim?" dan "Apa yang menyebabkan pesan dihapus?"

Misalnya, nilai tinggi untuk kolom droppedTooManyPendingMessages dapat menandakan bahwa instance aplikasi menerima volume pesan yang tidak dapat diciutkan melebihi batas FCM yaitu 100 pesan tertunda. Untuk menguranginya, pastikan aplikasi Anda menangani panggilan ke onDeletedMessages , dan pertimbangkan untuk mengirim pesan yang dapat diciutkan. Demikian pula, persentase droppedDeviceInactive yang tinggi dapat menjadi sinyal untuk memperbarui token pendaftaran di server Anda, menghapus token usang, dan menghentikan langganannya dari topik. Lihat Mengelola token pendaftaran FCM untuk praktik terbaik di area ini.

Persentase Performa Pengiriman

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

Persentase Wawasan Pesan

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

Apa perbedaan data ini dengan data yang diekspor ke BigQuery?

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

Sebaliknya, Firebase Cloud Messaging Data API memberikan detail gabungan tentang apa yang terjadi khususnya di Android Transport Layer (atau Langkah 3 Arsitektur FCM ). Data ini secara khusus memberikan wawasan tentang pengiriman pesan dari backend FCM ke Android SDK. Ini sangat berguna untuk menunjukkan tren mengapa pesan ditunda atau dibatalkan selama pengiriman ini.

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

  • Metrik gabungan hanya mengambil sampel sebagian dari semua pesan
  • Metrik gabungan dibulatkan
  • Kami tidak menampilkan metrik di bawah ambang batas privasi
  • Sebagian hasil pesan hilang karena pengoptimalan dalam cara kami mengelola volume lalu lintas yang besar.

Keterbatasan API

Garis Waktu Data Agregat

API akan mengembalikan data historis 7 hari; namun, data yang dikembalikan oleh API ini akan tertunda hingga 5 hari. Misalnya, pada tanggal 20 Januari, data untuk tanggal 9 Januari - 15 Januari akan tersedia, namun tidak untuk tanggal 16 Januari atau setelahnya. Selain itu, data disediakan dengan upaya terbaik. Jika terjadi gangguan data, FCM akan bekerja untuk memperbaikinya dan tidak akan mengisi ulang data setelah masalah diperbaiki. Dalam pemadaman 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 wawasan tentang tren pengiriman pesan secara luas. Namun, mereka tidak memberikan cakupan 100% dari semua skenario pesan. Skenario berikut adalah hasil yang diketahui tidak tercermin dalam metrik.

Pesan yang Diciutkan

Pesan yang telah diciutkan oleh pesan lain tidak akan muncul di kumpulan data.

Pesan ke perangkat yang tidak aktif

Pesan yang dikirim ke perangkat yang tidak aktif mungkin muncul atau tidak muncul di kumpulan data tergantung pada jalur data mana yang mereka ambil. Hal ini dapat menyebabkan beberapa kesalahan penghitungan di bidang droppedDeviceInactive dan pending .

Pesan ke perangkat dengan preferensi pengguna tertentu

Pengguna yang telah menonaktifkan pengumpulan informasi penggunaan dan diagnostik di perangkat mereka tidak akan menyertakan pesan mereka dalam penghitungan kami, sesuai dengan preferensi mereka.

Pembulatan dan Minimum

FCM sengaja membulatkan dan mengecualikan hitungan yang volumenya tidak cukup besar.

Ekspor data BigQuery

Anda dapat mengekspor data pesan ke BigQuery untuk analisis lebih lanjut. BigQuery memungkinkan Anda menganalisis data menggunakan BigQuery SQL, mengekspornya ke penyedia cloud lain, atau menggunakan data untuk model ML kustom Anda. Ekspor ke BigQuery mencakup semua data yang tersedia untuk pesan, apa pun jenis pesannya 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 lebih tinggi.
  • iOS 8.6.0 atau lebih tinggi
  • Firebase Web SDK 9.0.0 atau lebih tinggi

Lihat di bawah untuk detail tentang 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 Integrasi di konsol Firebase, klik Tautkan di kartu BigQuery .

      Halaman ini menampilkan opsi ekspor FCM untuk semua aplikasi yang mendukung FCM dalam proyek.

  2. Ikuti petunjuk di layar untuk mengaktifkan BigQuery.

Lihat Menautkan Firebase ke BigQuery untuk informasi lebih lanjut.

Saat Anda mengaktifkan ekspor BigQuery untuk Cloud Messaging:

  • Firebase mengekspor data Anda ke BigQuery. Perhatikan bahwa propagasi awal data untuk ekspor mungkin memerlukan waktu hingga 48 jam untuk diselesaikan.

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

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

  • Secara default, semua aplikasi di proyek Anda ditautkan ke BigQuery dan aplikasi apa pun yang nantinya Anda tambahkan ke proyek secara otomatis ditautkan ke BigQuery. Anda dapat mengelola aplikasi mana yang mengirim data .

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

Aktifkan ekspor data pengiriman pesan

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

Aktifkan ekspor data pengiriman untuk pemberitahuan lansiran

Karena hanya notifikasi lansiran 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 tentang Memodifikasi Konten di Notifikasi yang Baru Disampaikan .

Panggilan berikut harus dilakukan untuk setiap pemberitahuan yang diterima:

Cepat

// 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 membuat permintaan pengiriman menggunakan HTTP v1 API, pastikan untuk menentukan mutable-content = 1 di objek payload .

Aktifkan ekspor data pengiriman untuk pemberitahuan 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 pemberitahuan yang diterima:

Cepat

// 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 basi atau pendaftaran tidak aktif dapat menggelembungkan beberapa statistik ini.

Skema tabel yang diekspor adalah:

_PARTITIONTIME URUTAN WAKTU Kolom semu ini berisi stempel waktu untuk awal hari (dalam UTC) saat data dimuat. Untuk partisi YYYYMMDD, kolom semu ini berisi nilai TIMESTAMP('YYYY-MM-DD').
event_timestamp URUTAN WAKTU Stempel waktu acara seperti yang direkam oleh server
nomor proyek BILANGAN BULAT Nomor proyek mengidentifikasi proyek yang mengirim pesan
message_id RANGKAIAN ID pesan mengidentifikasi pesan. Dihasilkan dari ID Aplikasi dan stempel waktu, ID pesan mungkin, dalam beberapa kasus, tidak unik secara global.
instance_id RANGKAIAN ID unik aplikasi yang menjadi tujuan pengiriman pesan (bila tersedia). Ini bisa berupa ID instance atau ID penginstalan Firebase.
message_type RANGKAIAN Jenis pesan. Bisa berupa pesan Notifikasi atau pesan Data. Topik digunakan untuk mengidentifikasi pesan asli untuk pengiriman topik atau kampanye; pesan berikutnya adalah pemberitahuan atau pesan data.
sdk_platform RANGKAIAN Platform aplikasi penerima
nama aplikasi RANGKAIAN Nama paket untuk aplikasi Android atau id bundel untuk aplikasi iOS
collapse_key RANGKAIAN Kunci penciutan mengidentifikasi grup pesan yang dapat diciutkan. Saat perangkat tidak tersambung, hanya pesan terakhir dengan kunci penciutan tertentu yang akan diantrekan untuk pengiriman akhir
prioritas BILANGAN BULAT Prioritas pesan. Nilai yang valid adalah "normal" dan "tinggi". Di iOS, ini sesuai dengan prioritas APN 5 dan 10
ttl BILANGAN BULAT Parameter ini menentukan berapa lama (dalam detik) pesan harus disimpan di penyimpanan FCM jika perangkat offline
tema RANGKAIAN Nama topik tujuan pengiriman pesan (bila berlaku)
bulk_id BILANGAN BULAT ID massal mengidentifikasi grup pesan terkait, seperti pengiriman tertentu ke suatu topik
peristiwa RANGKAIAN Jenis acara. Nilai yang mungkin adalah:
  • MESSAGE_ACCEPTED: pesan diterima oleh server FCM dan permintaannya valid;
  • MESSAGE_DELIVERED: pesan telah dikirim ke FCM SDK aplikasi di perangkat. Secara default, kolom ini tidak disebarkan. Untuk mengaktifkan, ikuti petunjuk yang diberikan di setDeliveryMetricsExportToBigQuery(boolean) .
  • MISSING_REGISTRATIONS: permintaan ditolak karena pendaftaran tidak ada;
  • UNAUTHORIZED_REGISTRATION: pesan ditolak karena pengirim tidak berwenang mengirim ke pendaftaran;
  • MESSAGE_RECEIVED_INTERNAL_ERROR: ada kesalahan yang tidak ditentukan saat memproses permintaan pesan;
  • MISMATCH_SENDER_ID: permintaan untuk mengirim pesan ditolak karena ketidaksesuaian antara id pengirim yang mengirim pesan, dan yang dinyatakan untuk titik akhir;
  • 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 muatan melebihi batas;
  • AUTHENTICATION_ERROR: permintaan untuk mengirim pesan ditolak karena kesalahan autentikasi (periksa Kunci API yang digunakan untuk mengirim pesan);
  • INVALID_TTL: permintaan untuk mengirim pesan ditolak karena TTL tidak valid.
analytics_label RANGKAIAN Dengan HTTP v1 API , label analitik dapat diatur saat mengirim pesan, untuk menandai pesan untuk tujuan analitik

Apa yang dapat Anda lakukan dengan data yang diekspor?

Bagian berikut menawarkan contoh kueri yang dapat Anda jalankan di BigQuery terhadap data FCM yang diekspor.

Hitung pesan terkirim berdasarkan 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;

Hitung instance aplikasi unik yang ditargetkan 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';

Hitung pesan notifikasi yang dikirim

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

Hitung pesan data yang dikirim

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

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

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

Hitung durasi fanout untuk topik atau kampanye tertentu

Waktu mulai fanout adalah saat permintaan asli diterima, dan waktu berakhir adalah waktu saat pesan individu terakhir yang menargetkan 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;

Hitung persentase pesan 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;

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