ההתראות מ-Firebase פועלות באופן שונה בהתאם למצב של האפליקציה המקבלת – בחזית או ברקע. אם רוצים שאפליקציות בחזית יקבלו הודעות התראה או הודעות נתונים, צריך לכתוב קוד לטיפול בקריאה החוזרת (callback) של onMessageReceived
.
הסבר על ההבדל בין הודעות התראה להודעות נתונים מופיע בקטע סוגי הודעות.
טיפול בהודעות
כדי לקבל הודעות, צריך להשתמש בשירות שמרחיב את
FirebaseMessagingService
.
השירות צריך לשנות את הערכים של פונקציות ה-callbacks onMessageReceived
ו-onDeletedMessages
.
חלון הזמן לטיפול בהודעה עשוי להיות קצר מ-20 שניות, בהתאם לעיכובים שנצברו לפני הקריאה ל-onMessageReceived
, כולל עיכובים במערכת ההפעלה, זמן ההפעלה של האפליקציה, החסימה של ה-thread הראשי על ידי פעולות אחרות או זמן ארוך מדי של קריאות קודמות ל-onMessageReceived
. אחרי הזמן הזה, התנהגויות שונות של מערכת ההפעלה, כמו הפסקת תהליכים ב-Android או
מגבלות על ביצוע פעולות ברקע ב-Android O, עלולות להפריע לכם להשלים את העבודה.
השדה onMessageReceived
מופיע ברוב סוגי ההודעות, עם החרגות הבאות:
-
הודעות התראה שנשלחות כשהאפליקציה פועלת ברקע. במקרה כזה, ההתראה תישלח למגש המערכת של המכשיר. כשמשתמש מקייש על התראה, מרכז האפליקציות נפתח כברירת מחדל.
-
הודעות עם נתוני עומס ושימוש (payload) של התראה ונתונים, כשהן מתקבלות ברקע. במקרה כזה, ההתראה תישלח לסרגל המערכת של המכשיר, ועומס הנתונים יישלח ב-extras של ה-intent של הפעילות של מרכז האפליקציות.
בקצרה:
מצב האפליקציה | התראה | נתונים | שניהם |
---|---|---|---|
חזית | onMessageReceived |
onMessageReceived |
onMessageReceived |
רקע | מגש המערכת | onMessageReceived |
התראה: מגש המערכת נתונים: ב-extras של ה-intent. |
עריכת המניפסט של האפליקציה
כדי להשתמש ב-FirebaseMessagingService
, צריך להוסיף את הקטע הבא למניפסט של האפליקציה:
<service android:name=".java.MyFirebaseMessagingService" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service>
בנוסף, מומלץ להגדיר ערכי ברירת מחדל כדי להתאים אישית את המראה של ההתראות. אפשר לציין סמל ברירת מחדל וצבע ברירת מחדל בהתאמה אישית, שיחולו בכל פעם שלא מוגדרים ערכים מקבילים בתוכן של ההתראה.
מוסיפים את השורות הבאות בתוך התג application
כדי להגדיר את סמל ברירת המחדל והצבע בהתאמה אישית:
<!-- Set custom default icon. This is used when no icon is set for incoming notification messages. See README(https://goo.gl/l4GJaQ) for more. --> <meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@drawable/ic_stat_ic_notification" /> <!-- Set color used with incoming notification messages. This is used when no color is set for the incoming notification message. See README(https://goo.gl/6BKBk7) for more. --> <meta-data android:name="com.google.firebase.messaging.default_notification_color" android:resource="@color/colorAccent" />
ב-Android מוצג סמל ברירת המחדל המותאם אישית של
- כל הודעות ההתראות שנשלחות מ כלי היצירה של התראות.
- כל הודעת התראה שלא מגדירה את הסמל באופן מפורש במטען הייעודי (payload) של ההתראה.
Android משתמש בצבע ברירת המחדל המותאם אישית עבור:
- כל הודעות ההתראות שנשלחות מ כלי היצירה של התראות.
- כל הודעת התראה שלא מגדירה את הצבע באופן מפורש במטען הייעודי (payload) של ההתראה.
אם לא מגדירים סמל ברירת מחדל מותאם אישית ולא מגדירים סמל במטען הייעודי של ההתראה, מערכת Android מציגה את סמל האפליקציה בצבעים לבנים.
שינוי מברירת המחדל של onMessageReceived
שינוי ברירת המחדל של השיטה FirebaseMessagingService.onMessageReceived
מאפשר לבצע פעולות על סמך אובייקט RemoteMessage שהתקבל, ולקבל את נתוני ההודעה:
Kotlin+KTX
override fun onMessageReceived(remoteMessage: RemoteMessage) { // TODO(developer): Handle FCM messages here. // Not getting messages here? See why this may be: https://goo.gl/39bRNJ Log.d(TAG, "From: ${remoteMessage.from}") // Check if message contains a data payload. if (remoteMessage.data.isNotEmpty()) { Log.d(TAG, "Message data payload: ${remoteMessage.data}") // Check if data needs to be processed by long running job if (needsToBeScheduled()) { // For long-running tasks (10 seconds or more) use WorkManager. scheduleJob() } else { // Handle message within 10 seconds handleNow() } } // Check if message contains a notification payload. remoteMessage.notification?.let { Log.d(TAG, "Message Notification Body: ${it.body}") } // Also if you intend on generating your own notifications as a result of a received FCM // message, here is where that should be initiated. See sendNotification method below. }
Java
@Override public void onMessageReceived(RemoteMessage remoteMessage) { // TODO(developer): Handle FCM messages here. // Not getting messages here? See why this may be: https://goo.gl/39bRNJ Log.d(TAG, "From: " + remoteMessage.getFrom()); // Check if message contains a data payload. if (remoteMessage.getData().size() > 0) { Log.d(TAG, "Message data payload: " + remoteMessage.getData()); if (/* Check if data needs to be processed by long running job */ true) { // For long-running tasks (10 seconds or more) use WorkManager. scheduleJob(); } else { // Handle message within 10 seconds handleNow(); } } // Check if message contains a notification payload. if (remoteMessage.getNotification() != null) { Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody()); } // Also if you intend on generating your own notifications as a result of a received FCM // message, here is where that should be initiated. See sendNotification method below. }
שינוי מברירת המחדל של onDeletedMessages
יש מצבים שבהם FCM לא יכול להעביר הודעה. המצב הזה מתרחש כשיש יותר מדי הודעות (יותר מ-100) בהמתנה באפליקציה במכשיר מסוים בזמן החיבור, או אם המכשיר לא היה מחובר ל-FCM במשך יותר מחודש. במקרים כאלה, יכול להיות שתקבלו קריאה חוזרת ל-FirebaseMessagingService.onDeletedMessages()
. כשמכונה של אפליקציה מקבלת את הקריאה החוזרת הזו, היא צריכה לבצע סנכרון מלא עם שרת האפליקציה. אם לא שלחתם הודעה לאפליקציה במכשיר הזה ב-4 השבועות האחרונים, FCM לא יתקשר אל onDeletedMessages()
.
טיפול בהודעות התראה באפליקציה שפועלת ברקע
כשהאפליקציה פועלת ברקע, מערכת Android מפנה את הודעות ההתראות למגש המערכת. כשמשתמש מקייש על ההתראה, מרכז האפליקציות נפתח כברירת מחדל.
הנתונים האלה כוללים הודעות שמכילות גם הודעה וגם עומס נתונים (וכל ההודעות שנשלחות ממסוף ההתראות). במקרים כאלה, ההתראה מועברת לסרגל המערכת של המכשיר, ועומס הנתונים מועבר ב-extras של ה-intent של הפעילות של מרכז האפליקציות.
כדי לקבל תובנות לגבי העברת ההודעות לאפליקציה, אפשר לעיין ב לוח הבקרה של הדוחות FCM, שבו מתועד מספר ההודעות שנשלחו ונפתחו במכשירי Apple ו-Android, וגם נתונים לגבי 'חשיפות' (התראות שמוצגות למשתמשים) באפליקציות ל-Android.
קבלת הודעות FCM במצב הפעלה ישיר
מפתחים שרוצים לשלוח הודעות FCM לאפליקציות עוד לפני שהמכשיר נעול יכולים לאפשר לאפליקציה ל-Android לקבל הודעות כשהמכשיר נמצא במצב הפעלה ישירה. לדוגמה, יכול להיות שתרצו שמשתמשי האפליקציה יקבלו התראות על אזעקות גם במכשיר נעול.
כשמפתחים את התרחיש לדוגמה הזה, צריך לפעול לפי השיטות המומלצות וההגבלות הכלליות לגבי מצב אתחול ישיר. חשוב במיוחד להביא בחשבון את החשיפה של הודעות שמופעלת בהן הפעלה ישירה. כל משתמש שיש לו גישה למכשיר יכול לראות את ההודעות האלה בלי להזין את פרטי הכניסה של המשתמש.
דרישות מוקדמות
- צריך להגדיר את המכשיר למצב הפעלה ישיר.
- במכשיר צריכה להיות מותקנת גרסה עדכנית של Google Play Services (19.0.54 ואילך).
- כדי לקבל הודעות מ-FCM, האפליקציה צריכה להשתמש ב-FCM SDK (
com.google.firebase:firebase-messaging
).
הפעלת טיפול בהודעות במצב הפעלה ישיר באפליקציה
בקובץ Gradle ברמת האפליקציה, מוסיפים תלות בספריית התמיכה בהפעלה ישירה של FCM:
implementation 'com.google.firebase:firebase-messaging-directboot:20.2.0'
כדי להפוך את האפליקציה למודעת הפעלה ישירה של
FirebaseMessagingService
, מוסיפים את המאפייןandroid:directBootAware="true"
למניפסט של האפליקציה:<service android:name=".java.MyFirebaseMessagingService" android:exported="false" android:directBootAware="true"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service>
חשוב לוודא ש-FirebaseMessagingService
הזה יכול לפעול במצב אתחול ישיר. צריך לעמוד בדרישות הבאות:
- השירות לא אמור לגשת לאחסון המוגן באמצעות פרטי הכניסה בזמן שהוא פועל במצב הפעלה ישיר.
- אסור לשירות לנסות להשתמש ברכיבים כמו
Activities
,BroadcastReceivers
אוServices
אחרים שלא מסומנים כרכיבים שתומכים בהפעלה ישירה, בזמן שהוא פועל במצב הפעלה ישירה. - בנוסף, אסור לספריות שבהן השירות משתמש לגשת לאחסון שמוגן באמצעות פרטי כניסה, או לבצע קריאה לרכיבים שלא תומכים ב-directBootAware במהלך ההפעלה במצב הפעלה ישירה. כלומר, כל הספריות שבהן האפליקציה משתמשת ומתבצעת קריאה אליהן מהשירות צריכות להיות מותאמות לטעינה ישירה, או שהאפליקציה צריכה לבדוק אם היא פועלת במצב טעינה ישירה ולא לבצע קריאה אליהן במצב הזה. לדוגמה, ערכות ה-SDK של Firebase פועלות עם הפעלה ישירה (אפשר לכלול אותן באפליקציה בלי לגרום לקריסה שלה במצב הפעלה ישירה), אבל ממשקי API רבים של Firebase לא תומכים בקריאה במצב הפעלה ישירה.
- אם האפליקציה משתמשת ב-
Application
בהתאמה אישית, ה-Application
צריך להיות תומך גם בהפעלה ישירה (אין גישה לאחסון שמוגן בפרטי כניסה במצב הפעלה ישירה).
להנחיות לשליחת הודעות למכשירים במצב הפעלה ישירה, ראו שליחת הודעות שתומכות בהפעלה ישירה.