ב-FCM יש שלוש קבוצות של כלים שיעזרו לכם לקבל תובנות לגבי העברת ההודעות:
- Firebase דוחות מסירה של הודעות במסוף
- מדדי העברה מצטברים של Android SDK מ-Firebase Cloud Messaging Data API
- ייצוא נתונים מקיף ל-Google BigQuery
כל כלי הדיווח המתוארים בדף הזה דורשים את Google Analytics כדי לפעול. אם Google Analytics לא מופעל בפרויקט שלכם, אפשר להגדיר אותו בכרטיסייה אינטגרציות בהגדרות הפרויקט ב-Firebase.
חשוב לזכור שדיווח על רבים מהנתונים הסטטיסטיים בדף הזה עשוי להתעכב עד 24 שעות בגלל קיבוץ של נתוני ניתוח.
דוחות מסירת הודעות
בכרטיסייה Reports במסוף Firebase אפשר לראות את הנתונים הבאים לגבי הודעות שנשלחו לערכות FCM SDK של Android או Apple, כולל הודעות שנשלחו דרך מחבר ההתראות וממשקי FCM API:
- שליחה – הודעת הנתונים או הודעת ההתראה נוספו לתור לצורך שליחה, או שהועברו בהצלחה לשירות של צד שלישי, כמו APN, לצורך שליחה. למידע נוסף, ראו משך החיים של הודעה.
- התקבלה (זמין רק במכשירי Android) – הודעת הנתונים או הודעת ההתראה התקבלו באפליקציה. הנתונים האלה זמינים כשבמכשיר Android המקבל מותקנת גרסת FCM SDK 18.0.1 ואילך.
- חשיפות (זמינות רק להתרעות במכשירי Android) – ההתראה הוצגה במכשיר בזמן שהאפליקציה הייתה ברקע.
- פתיחה – המשתמש פתח את הודעת ההתראה. הנתון הזה מדווח רק לגבי התראות שהתקבלו כשהאפליקציה הייתה ברקע.
הנתונים האלה זמינים לכל ההודעות עם עומס נתונים של התראה ולכל הודעות הנתונים המתויגות. למידע נוסף על תוויות, ראו הוספת תוויות של ניתוח נתונים להודעות.
כשמציגים דוחות של הודעות, אפשר להגדיר טווח תאריכים לנתונים שיוצגו, עם אפשרות לייצוא לקובץ CSV. אפשר גם לסנן לפי הקריטריונים הבאים:
- פלטפורמה (iOS או Android)
- אפליקציה
- תוויות מותאמות אישית של ניתוח נתונים
הוספת תוויות ניתוח נתונים להודעות
תיוג הודעות שימושי מאוד לניתוח מותאם אישית, ומאפשר לסנן את נתוני ההעברה לפי תוויות או קבוצות של תוויות. אפשר להוסיף תווית לכל הודעה שנשלחת דרך ה-API של HTTP v1 על ידי הגדרת השדה fcmOptions.analyticsLabel
באובייקט message, או בשדות AndroidFcmOptions
או ApnsFcmOptions
שספציפיים לפלטפורמה.
תוויות Analytics הן מחרוזות טקסט בפורמט ^[a-zA-Z0-9-_.~%]{1,50}$
.
התוויות יכולות לכלול אותיות קטנות וגדולות, מספרים ואת הסמלים הבאים:
-
~
%
האורך המקסימלי הוא 50 תווים. אפשר לציין עד 100 תוויות ייחודיות ביום. לא יתבצע דיווח על הודעות עם תוויות שנוספו מעבר למגבלה הזו.
בכרטיסייה Firebase Reports (דוחות) של הודעות המסוף, אפשר לחפש ברשימת כל התוויות הקיימות ולהחיל אותן בנפרד או בשילוב כדי לסנן את הנתונים הסטטיסטיים שמוצגים.
נתוני העברה מצטברים דרך FCM Data API
בעזרת Cloud Messaging Data API של Firebase אפשר לאחזר מידע שיכול לעזור להבין את התוצאות של בקשות להודעות שמטורגטות לאפליקציות ל-Android. ה-API מספק נתונים נצברים מכל מכשירי Android בפרויקט עם אפשרות לאיסוף נתונים. הנתונים האלה כוללים פרטים על אחוז ההודעות שנשלחו ללא עיכוב, ועל מספר ההודעות שהועברו באיחור או שהושמטו בשכבת התעבורה של Android. הערכת הנתונים האלה יכולה לחשוף מגמות רחבות בשליחת ההודעות ולעזור לכם למצוא דרכים יעילות לשיפור הביצועים של בקשות השליחה. במאמר ציר זמן של נתונים מצטברים מפורט מידע על הזמינות של טווחי התאריכים בדוחות.
ה-API מספק את כל הנתונים שזמינים לאפליקציה מסוימת. מאמרי העזרה של ה-API
איך מתבצע פירוט הנתונים?
נתוני ההעברה מפורטים לפי אפליקציה, תאריך ותווית Analytics.
קריאה ל-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 Export מופיעים יומנים נפרדים של הודעות על אישור ההודעות על ידי הקצה העורפי של FCM ועל העברת ההודעות ב-SDK במכשיר (שלבים 2 ו-4 בארכיטקטורת FCM). הנתונים האלה מאפשרים לוודא שההודעות נשלחו ונקלטו. בקטע הבא מפורט מידע נוסף על ייצוא נתונים מ-BigQuery.
לעומת זאת, Firebase Cloud Messaging Data API מספק פרטים מצטברים על מה שקורה באופן ספציפי בשכבת התעבורה של Android (או שלב 3 בארכיטקטורה של FCM). הנתונים האלה מספקים תובנות ספציפיות לגבי העברת ההודעות מקצוות העורפי של FCM ל-Android SDK. הנתונים האלה שימושיים במיוחד להצגת מגמות לגבי הסיבות לעיכובים או להפסקות בהעברת ההודעות.
במקרים מסוימים, יכול להיות ששתי קבוצות הנתונים לא יהיו זהות לחלוטין בגלל:
- המדדים המצטברים דוגמים רק חלק מכל ההודעות
- המדדים המצטברים עגולים
- המדדים לא מוצגים מתחת לסף המינימלי בנושא פרטיות
- חלק מהתוצאות של ההודעות חסרות בגלל אופטימיזציה של האופן שבו אנחנו מנהלים את נפח התנועה הגדול.
מגבלות ה-API
צירי זמן של נתונים מצטברים
ה-API יחזיר נתונים היסטוריים של 7 ימים, אבל הנתונים שיוחזרו על ידי ה-API הזה יתקבלו באיחור של עד 5 ימים. לדוגמה, מ-20 בינואר עד 15 בינואר, הנתונים יהיו זמינים מ-9 בינואר עד 15 בינואר, אבל לא מ-16 בינואר ואילך. בנוסף, הנתונים ניתנים במסגרת האפשרויות הקיימות. במקרה של הפסקה זמנית בשירות הנתונים, צוות FCM יפעל לתיקון הבעיה ולא ימלא את הנתונים לאחר תיקון הבעיה. אם מדובר בהפסקות זמניות ארוכות יותר, יכול להיות שהנתונים לא יהיו זמינים במשך שבוע או יותר.
כיסוי נתונים
המדדים שסופקו על ידי Firebase Cloud Messaging Data API נועדו לספק תובנות לגבי מגמות רחבות של שליחת הודעות. עם זאת, הן לא מספקות כיסוי מלא של כל תרחישי ההודעות. התרחישים הבאים הם תוצאות ידועות שלא משתקפות במדדים.
הודעות שפג תוקפן
אם התוקף של Time To Live (TTL) יפוג אחרי סיום תאריך היומן הנתון, ההודעה לא תיספר כ-droppedTtlExpired
בתאריך הזה.
הודעות למכשירים לא פעילים
יכול להיות שהודעות שנשלחות למכשירים לא פעילים עדיין יופיעו במערך הנתונים, או לא, בהתאם לנתיב הנתונים שבו הן עוברות. זה עלול לגרום לחוסר ספירה בשדות droppedDeviceInactive
ו-pending
.
הודעות למכשירים עם העדפות משתמש מסוימות
בהתאם להעדפות שלהם, ההודעות של משתמשים שהשביתו את האיסוף של נתוני שימוש ונתוני אבחון במכשירים שלהם לא ייכללו בספירה שלנו.
עיגול וערכים מינימליים
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 ול-iOS.
כדי להתחיל, מקשרים את הפרויקט ל-BigQuery:
בחר אחת מהאפשרויות הבאות:
פותחים את כלי היצירה של התראות ולוחצים על Access BigQuery (גישה ל-BigQuery) בתחתית הדף.
בדף Integrations (שילובים) במסוף Firebase, לוחצים על Link (קישור) בכרטיס BigQuery.
בדף הזה מוצגות אפשרויות הייצוא של FCM לכל האפליקציות שפועלות עם FCM בפרויקט.
פועלים לפי ההוראות במסך כדי להפעיל את BigQuery.
למידע נוסף, קראו את המאמר קישור בין Firebase ל-BigQuery.
כשמפעילים את הייצוא של BigQuery עבור Cloud Messaging:
מערכת Firebase מייצאת את הנתונים אל BigQuery. שימו לב שתהליך ההפצה הראשונית של הנתונים לייצוא עשוי להימשך עד 48 שעות.
- אתם יכולים לתזמן באופן ידני מילוי חוסרים בנתונים עד 30 הימים האחרונים.
אי אפשר לשנות את המיקום אחרי שיוצרים את מערך הנתונים, אבל אפשר להעתיק את מערך הנתונים למיקום אחר או להעביר אותו ידנית למיקום אחר (וליצור אותו מחדש). מידע נוסף זמין במאמר שינוי המיקום של מערך הנתונים.
מערכת Firebase מגדירה סנכרון קבוע של הנתונים מפרויקט Firebase אל BigQuery. פעולות הייצוא היומיות האלה מתחילות בשעה 04:00 לפי שעון החוף המערבי בארה"ב, ובדרך כלל מסתיימות תוך 24 שעות.
כברירת מחדל, כל האפליקציות בפרויקט מקושרות אל BigQuery וכל האפליקציות שתוסיפו לפרויקט במועד מאוחר יותר יקושרו באופן אוטומטי אל BigQuery. אפשר לקבוע אילו אפליקציות ישלחו נתונים.
כדי להשבית את הייצוא של BigQuery, צריך לבטל את הקישור של הפרויקט במסוף Firebase.
הפעלת ייצוא של נתוני שליחת הודעות
במכשירי Android עם FCM SDK מגרסה 20.1.0 ואילך אפשר להפעיל את הייצוא של נתוני העברת ההודעות באפליקציה. ייצוא הנתונים מושבת כברירת מחדל ברמת האפליקציה. הפעלה פרוגרמטית ברמת מכונה של אפליקציה מאפשרת לבקש ממשתמשי הקצה הרשאה לנתח את נתוני מסירת ההודעות שלהם (מומלץ). אם שני הערכים מוגדרים, הערך ברמת מכונה של האפליקציה מבטל את הערך ברמת האפליקציה.
לפני שמפעילים את האפשרויות האלה, קודם צריך ליצור את הקישור FCM-BiqQuery לפרויקט, כפי שמתואר בייצוא נתונים ל-BigQuery.
הפעלת ייצוא של נתוני העברה למכונות של אפליקציות
ברוב המקרים, מומלץ להפעיל את הייצוא של נתוני העברת ההודעות רק ברמת מכונה של האפליקציה, ולהשאיר אותו מושבת ברמת האפליקציה.
FirebaseMessaging.getInstance().setDeliveryMetricsExportToBigQuery(true)
הפעלת ייצוא של נתוני מסירה עבור אפליקציה
אם אתם מעדיפים להפעיל את הייצוא ברמת האפליקציה, חשוב לא לבצע קריאה ל-method setDeliveryMetricsExportToBigQuery
ולהוסיף את המאפיין הבא לאובייקט האפליקציה במניפסט של האפליקציה:
<application>
<meta-data android:name="delivery_metrics_exported_to_big_query_enabled"
android:value="true" />
</application>
אילו נתונים מיוצאים ל-BigQuery?
חשוב לזכור שטירגוט של אסימונים לא תקינים או של רישומים לא פעילים עלול להגדיל חלק מהנתונים הסטטיסטיים האלה.
הסכימה של הטבלה המיוצאת היא:
_PARTITIONTIME | TIMESTAMP | העמודה הזו מכילה חותמת זמן לתחילת היום (לפי שעון UTC) שבו הנתונים נטענו. במחיצה YYYYMMDD, העמודה הזו מכילה את הערך TIMESTAMP('YYYY-MM-DD'). |
event_timestamp | חותמת זמן | חותמת הזמן של האירוע כפי שתועדה על ידי השרת |
project_number | מספר שלם | מספר הפרויקט מזהה את הפרויקט ששלח את ההודעה |
message_id | מחרוזת | מזהה ההודעה מזהה הודעה. מזהה ההודעה נוצר מ-App ID ומחותמת הזמן, ובמקרים מסוימים הוא לא ייחודי גלובלית. |
instance_id | מחרוזת | המזהה הייחודי של האפליקציה שאליה נשלחת ההודעה (אם הוא זמין). הוא יכול להיות מזהה מכונה או מזהה התקנה של Firebase. |
message_type | מחרוזת | סוג ההודעה. יכולה להיות הודעת התראה או הודעת נתונים. הנושא משמש לזיהוי ההודעה המקורית לשליחה של נושא או קמפיין. ההודעות הבאות הן התראות או הודעות נתונים. |
sdk_platform | מחרוזת | הפלטפורמה של האפליקציה הנמען |
app_name | מחרוזת | שם החבילה של אפליקציות ל-Android או מזהה החבילה של אפליקציות ל-iOS |
collapse_key | מחרוזת | מפתח הכיווץ מזהה קבוצה של הודעות שאפשר לכווץ. כשמכשיר לא מחובר, רק ההודעה האחרונה עם מפתח כיווץ נתון נמצאת בתור למסירה הסופית |
הרשמה בעדיפות | מספר שלם | עדיפות ההודעה. הערכים החוקיים הם 'רגיל' ו'גבוה'. ב-iOS, הן תואמות לעדיפויות 5 ו-10 של ה-APN |
ttl | מספר שלם | הפרמטר הזה מציין למשך כמה זמן (בשניות) ההודעה צריכה להישמר באחסון FCM אם המכשיר במצב אופליין |
נושא | מחרוזת | שם הנושא שאליו נשלחה הודעה (אם רלוונטי) |
bulk_id | מספר שלם | המזהה הכולל מזהה קבוצה של הודעות קשורות, כמו שליחה ספציפית לנושא |
אירוע | מחרוזת | סוג האירוע.
הערכים האפשריים הם:
|
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;