קבלת הודעות באמצעות העברת הודעות בענן ב-Firebase

במדריך הזה מוסבר איך להגדיר את Firebase Cloud Messaging באפליקציות הלקוח לנייד ולאינטרנט כדי לקבל הודעות בצורה מהימנה.

כדי לקבל הודעות, אפשר להשתמש בשירות שמרחיב את FirebaseMessagingService. השירות שלכם צריך לבטל את ההגדרות של הקריאות החוזרות onMessageReceived ו-onDeletedMessages. דוגמה מלאה מופיעה במדריך למתחילים של Firebase Cloud Messaging.

onMessageReceived מסופק לרוב סוגי ההודעות, למעט:

  • הודעות התראה שנמסרות כשהאפליקציה פועלת ברקע. במקרה הזה, ההתראה מועברת למגש המערכת של המכשיר. כשמשתמש מקיש על הודעה, מרכז האפליקציות נפתח כברירת מחדל.

  • הודעות עם מטען ייעודי (payload) של התראה וגם של נתונים, כשהן מתקבלות ברקע. במקרה כזה, ההתראה מועברת למגש המערכת של המכשיר, ומטען הנתונים מועבר בתוספים של הכוונה של פעילות מרכז האפליקציות.

בקצרה:

מצב האפליקציה התראה נתונים שניהם
חזית onMessageReceived onMessageReceived onMessageReceived
רקע מגש המערכת onMessageReceived התראה: מגש המערכת נתונים: בתוספות של הכוונה.

מידע נוסף על סוגי הודעות זמין במאמר התראות והודעות נתונים.

ל-callback של onMessageReceived יש חלון ביצוע קצר. יש הרבה גורמים שיכולים להשפיע על משך הזמן של החלון הזה, כולל עיכובים במערכת ההפעלה, זמן ההפעלה של האפליקציה, חסימה של ה-thread הראשי על ידי פעולות אחרות או קריאות קודמות ל-onMessageReceived שנמשכות יותר מדי זמן.

לכן, כדאי להימנע ממשימות שפועלות לאורך זמן (כמו אחזור תמונות משרת כדי להציג אותן בהתראה) ב-onMessageReceived, ובמקום זאת לתזמן משימה באמצעות WorkManager כדי לטפל בכל משימה שעלולה להימשך יותר מכמה שניות. מידע נוסף על עדיפות ההודעות ואיך היא משפיעה על העיבוד זמין במאמר עיבוד הודעות בעדיפות גבוהה ובעדיפות רגילה.

עריכת קובץ המניפסט של האפליקציה

כדי להשתמש ב-FirebaseMessagingService, צריך להוסיף את השורות הבאות למניפסט של האפליקציה:

<service
    android:name=".java.MyFirebaseMessagingService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

מומלץ להגדיר ערכי ברירת מחדל כדי להתאים אישית את המראה של ההתראות. אתם יכולים לציין סמל ברירת מחדל מותאם אישית וצבע ברירת מחדל מותאם אישית, שיוחלו בכל מקרה שלא מוגדרים ערכים מקבילים במטען הייעודי (payload) של ההתראה.

כדי להגדיר את סמל ברירת המחדל המותאם אישית ואת הצבע המותאם אישית, מוסיפים את השורות האלה בתוך התג 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) של ההתראה.

אם לא מוגדר סמל ברירת מחדל מותאם אישית ולא מוגדר סמל במטען הייעודי (payload) של ההתראה, מערכת Android מציגה את סמל האפליקציה שמוצג בלבן.

שינוי של onMessageReceived

אפשר לבצע פעולות על סמך האובייקט RemoteMessage שהתקבל ולקבל את נתוני ההודעה על ידי ביטול השיטה FirebaseMessagingService.onMessageReceived:

Kotlin

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 מפנה את הודעות ההתראה למגש המערכת. כברירת מחדל, הקשה של משתמש על ההתראה פותחת את מרכז האפליקציות.

זה כולל הודעות שמכילות גם התראה וגם מטען נתונים (וכל ההודעות שנשלחות ממסוף ההתראות). במקרים כאלה, ההתראה מועברת למגש המערכת של המכשיר, ומטען הנתונים מועבר בתוספים של ה-Intent של פעילות מרכז האפליקציות.

למידע נוסף על מסירת הודעות לאפליקציה, אפשר לעיין ב FCMלוח הבקרה של הדוחות, שבו מתועד מספר ההודעות שנשלחו ונפתחו במכשירי Apple ובמכשירי Android, וגם נתונים לגבי 'חשיפות' (התראות שהמשתמשים ראו) באפליקציות ל-Android.