קבלת הודעות באפליקציות ל-Android

בחירת פלטפורמה: iOS+‎ Android אינטרנט Flutter Unity C++‎


כדי לקבל הודעות, אפשר להשתמש בשירות שמרחיב את FirebaseMessagingService. אם אתם עוברים ל-AndroidConfigV2, אתם צריכים להטמיע את פונקציות ה-callback הייעודיות onNotificationReceived ו-onBackgroundSyncReceived, כמו שמתואר במאמר עדכון פונקציות ה-callback של לקוח Android. בהודעות AndroidConfig (גרסה 1) מדור קודם, השירות צריך לשנות את הקריאות החוזרות (callbacks) של onMessageReceived ו-onDeletedMessages. דוגמה מלאה מופיעה במדריך למתחילים של העברת הודעות בענן ב-Firebase.

השדה onMessageReceived מופיע ברוב סוגי ההודעות, חוץ מהמקרים הבאים:

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

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

בקצרה:

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

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

הקריאה החוזרת (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 מציגה את סמל ברירת המחדל המותאם אישית ומשתמשת בו עבור

  • כל ההודעות שנשלחות מהכלי לניסוח הודעות במסוף Firebase.

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

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

כדי לקבל תובנות לגבי מסירת ההודעות לאפליקציה, נכנסים ללוח הבקרה DevOps & Engagement (DevOps ומעורבות) > Messaging (העברת הודעות) > Reports (דוחות) במסוף Firebase. בלוח הבקרה הזה מתועד מספר ההודעות שנשלחו ונפתחו במכשירי אפל ובמכשירי Android, וגם נתונים לגבי "חשיפות" (התראות שהמשתמשים ראו) באפליקציות ל-Android.