איך מתחילים להשתמש בהעברת הודעות בענן ב-Firebase באפליקציות ל-Android

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


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

FCM לקוחות נדרשים למכשירים עם Android בגרסה 7.0 ומעלה, שמותקנת בהם גם אפליקציית חנות Google Play, או לאמולטור עם Android בגרסה 7.0 עם Google APIs. חשוב לדעת שאתם לא מוגבלים לפריסת אפליקציות ל-Android דרך חנות Google Play.

הגדרת ה-SDK

אם עדיין לא הוספתם את Firebase לפרויקט Android, אתם צריכים להוסיף אותו.

כדי ליהנות מחוויית שימוש אופטימלית ב-FCM, מומלץ מאוד להפעיל את Google Analytics בפרויקט. ‫Google Analytics היא דרישה לדיווח על מסירת הודעות ב-FCM.

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

מוסיפים את השורות הבאות למניפסט של האפליקציה:

  • שירות שמרחיב את FirebaseMessagingService. ההרשאה הזו נדרשת אם רוצים לבצע טיפול כלשהו בהודעות מעבר לקבלת התראות באפליקציות ברקע. כדי לקבל התראות באפליקציות שפועלות בחזית, לקבל נתוני מטען ועוד, צריך להרחיב את השירות הזה.
  • <service
        android:name=".java.MyFirebaseMessagingService"
        android:exported="false">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
  • (אופציונלי) בתוך רכיב האפליקציה, רכיבי מטא-נתונים להגדרת סמל וצבע ברירת מחדל להתראות. מערכת Android משתמשת בערכים האלה בכל פעם שהודעות נכנסות לא מגדירות באופן מפורש סמל או צבע.
  • <!-- 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 מגרסה 8.0 (רמת API‏ 26) ואילך, יש תמיכה ב ערוצי התראות ומומלץ להשתמש בהם. ‫FCM מספק ערוץ התראות שמוגדר כברירת מחדל עם הגדרות בסיסיות. אם אתם מעדיפים ליצור ערוץ ברירת מחדל משלכם ולהשתמש בו, צריך להגדיר את default_notification_channel_id למזהה של אובייקט ערוץ ההתראות, כמו שמוצג כאן. FCM ישתמש בערך הזה בכל פעם שהודעות נכנסות לא מגדירות במפורש ערוץ התראות. למידע נוסף, קראו את המאמר ניהול ערוצי התראות.
  • <meta-data
        android:name="com.google.firebase.messaging.default_notification_channel_id"
        android:value="@string/default_notification_channel_id" />

בקשת הרשאה לשליחת התראות בתחילת ההפעלה ב-Android מגרסה 13 ואילך

ב-Android 13 מוצגת הרשאה בתחילת ההפעלה חדשה להצגת התראות. השינוי הזה משפיע על כל האפליקציות שפועלות ב-Android מגרסה 13 ואילך ומשתמשות בהתראות של FCM.

כברירת מחדל, ערכת ה-SDK של FCM (גרסה 23.0.6 ואילך) כוללת את ההרשאה POST_NOTIFICATIONS שמוגדרת במניפסט. עם זאת, האפליקציה שלך תצטרך גם לבקש את גרסת ההרשאה בזמן הריצה באמצעות הקבוע android.permission.POST_NOTIFICATIONS. האפליקציה לא תוכל להציג התראות עד שהמשתמש יאשר את ההרשאה הזו.

כדי לבקש את ההרשאה החדשה בתחילת ההפעלה:

Kotlin

// Declare the launcher at the top of your Activity/Fragment:
private val requestPermissionLauncher = registerForActivityResult(
    ActivityResultContracts.RequestPermission(),
) { isGranted: Boolean ->
    if (isGranted) {
        // FCM SDK (and your app) can post notifications.
    } else {
        // TODO: Inform user that that your app will not show notifications.
    }
}

private fun askNotificationPermission() {
    // This is only necessary for API level >= 33 (TIRAMISU)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) ==
            PackageManager.PERMISSION_GRANTED
        ) {
            // FCM SDK (and your app) can post notifications.
        } else if (shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS)) {
            // TODO: display an educational UI explaining to the user the features that will be enabled
            //       by them granting the POST_NOTIFICATION permission. This UI should provide the user
            //       "OK" and "No thanks" buttons. If the user selects "OK," directly request the permission.
            //       If the user selects "No thanks," allow the user to continue without notifications.
        } else {
            // Directly ask for the permission
            requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
        }
    }
}

Java

// Declare the launcher at the top of your Activity/Fragment:
private final ActivityResultLauncher<String> requestPermissionLauncher =
        registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {
            if (isGranted) {
                // FCM SDK (and your app) can post notifications.
            } else {
                // TODO: Inform user that that your app will not show notifications.
            }
        });

private void askNotificationPermission() {
    // This is only necessary for API level >= 33 (TIRAMISU)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) ==
                PackageManager.PERMISSION_GRANTED) {
            // FCM SDK (and your app) can post notifications.
        } else if (shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS)) {
            // TODO: display an educational UI explaining to the user the features that will be enabled
            //       by them granting the POST_NOTIFICATION permission. This UI should provide the user
            //       "OK" and "No thanks" buttons. If the user selects "OK," directly request the permission.
            //       If the user selects "No thanks," allow the user to continue without notifications.
        } else {
            // Directly ask for the permission
            requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS);
        }
    }
}

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

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

הרשאות לשליחת התראות באפליקציות שמטרגטות ל-Android 12L (רמת API ‏32) ומטה

מערכת Android מבקשת מהמשתמש באופן אוטומטי הרשאה בפעם הראשונה שהאפליקציה יוצרת ערוץ התראות, כל עוד האפליקציה פועלת בחזית. עם זאת, יש כמה נקודות חשובות לגבי התזמון של יצירת הערוץ ובקשות ההרשאה:

  • אם האפליקציה יוצרת את ערוץ ההתראות הראשון שלה כשהיא פועלת ברקע, כמו שקורה ב-SDK של FCM כשמתקבלת התראה של FCM, מערכת Android לא תאפשר להציג את ההתראה ולא תבקש מהמשתמש הרשאה לשליחת התראות עד לפעם הבאה שהאפליקציה תיפתח. כלומר, כל ההתראות שיתקבלו לפני שהמשתמש יפתח את האפליקציה ויאשר את ההרשאה יאבדו.
  • מומלץ מאוד לעדכן את האפליקציה כך שתטרגט ל-Android מגרסה 13 ואילך, כדי לנצל את ממשקי ה-API של הפלטפורמה לבקשת הרשאה. אם זה לא אפשרי, האפליקציה צריכה ליצור ערוצי התראות לפני ששולחים התראות לאפליקציה כדי להפעיל את תיבת הדו-שיח של ההרשאה לשליחת התראות, ולוודא שאף התראה לא תאבד. מידע נוסף זמין במאמר שיטות מומלצות בנושא הרשאות לשליחת התראות.

אופציונלי: הסרת ההרשאה של POST_NOTIFICATIONS

כברירת מחדל, ה-SDK של FCM כולל את ההרשאה POST_NOTIFICATIONS. אם האפליקציה לא משתמשת בהודעות התראה (בין אם דרך FCM התראות, דרך SDK אחר או דרך פרסום ישיר של האפליקציה) ואתם לא רוצים שההרשאה תיכלל באפליקציה, אתם יכולים להסיר אותה באמצעות הסמן remove של כלי המיזוג של קובצי המניפסט. חשוב לזכור: הסרת ההרשאה הזו תמנע את ההצגה של כל ההתראות, לא רק של ההתראות של FCM. מוסיפים את הטקסט הבא לקובץ המניפסט של האפליקציה:

<uses-permission android:name="android.permission.POST_NOTIFICATIONS" tools:node="remove"/>

גישה למזהה ההתקנה של Firebase

בהפעלה הראשונית של האפליקציה, FCM SDK רושם את מופע האפליקציה ב-FCM ומחזיר מזהה למופע האפליקציה. אם רוצים לטרגט מופעים ספציפיים של האפליקציה, צריך לגשת למזהה הזה על ידי הרחבה של FirebaseMessagingService ושינוי של onRegistered(). מומלץ לאחזר את המזהה העדכני ביותר, כי המזהה יכול להשתנות אחרי ההפעלה הראשונית.

הפעלת הרישום באמצעות מזהה ההתקנה של Firebase

כדי לאפשר רישום של מופע האפליקציה ב-FCM באמצעות מזהה ההתקנה של Firebase‏ (FID), צריך להוסיף את דגל המטא-נתונים הבא לקובץ AndroidManifest.xml:
<meta-data
    android:name="firebase_messaging_installation_id_enabled"
    android:value="true" />

מטמיעים את הקריאה החוזרת (callback) של onRegistered()

אחרי שמופעי האפליקציה נרשמים ב-FCM, אפשר לטרגט אותם באמצעות מזהה ההתקנה של Firebase‏ (FID). כדי לאחזר את מזהה ה-FID בזמן הרישום, מטמיעים את הקריאה החוזרת (callback) של onRegistered(). אחרי שרושמים מופע של אפליקציה, ערכת ה-SDK‏ FCM עוקבת אוטומטית אחרי שינויים ב-FID ומפעילה את הקריאה החוזרת כשמזוהה שינוי. כשההפעלה האוטומטית מופעלת, ה-SDK של FCM מסתנכרן באופן אוטומטי עם הקצה העורפי של FCM כדי לשמור על עדכניות הרישום, ומפעיל את הקריאה החוזרת (callback) כדי לוודא שבשרת האפליקציה יש את המזהה הנוכחי. כדי להגן מפני אובדן של מזהה Firebase או מזהי Firebase מיושנים, צריך לשלוח את מזהה Firebase לשרת האפליקציה בכל פעם שהקריאה החוזרת הזו מופעלת.

Kotlin

  /**
   * There are three scenarios when `onRegistered` is called:
   * 1) Every time a manual `register()` call finishes successfully
   * 2) Whenever the FID is changed and the app is re-registered with FCM via the new FID.
   * 3) Automatically on app startup or routine sync when auto-initialization is enabled.
   * Under #2, there are three scenarios when the existing FID is changed:
   * A) App is restored to a new device
   * B) User uninstalls/reinstalls the app
   * C) User clears app data
   */
  override fun onRegistered(installationId: String) {
      Log.d(TAG, "Registered installation ID: $installationId")

      // Send the Firebase Installation ID to your app server.
      sendRegistrationToServer(installationId)
  }
    

Java

  /**
   * There are three scenarios when `onRegistered` is called:
   * 1) Every time a manual `register()` call finishes successfully
   * 2) Whenever the FID is changed and the app is re-registered with FCM via the new FID
   * 3) Automatically on app startup or routine sync when auto-initialization is enabled.
   * Under #2, there are three scenarios when the existing FID is changed:
   * A) App is restored to a new device
   * B) User uninstalls/reinstalls the app
   * C) User clears app data
   */
  @Override
  public void onRegistered(@NonNull String installationId) {
      Log.d(TAG, "Registered installation ID: " + installationId);

      // Send the Firebase Installation ID to your app server.
      sendRegistrationToServer(installationId);
  }
    

רישום ידני כשההפעלה האוטומטית מושבתת

אם אתם צריכים להשבית את ההפעלה האוטומטית, ה-SDK של FCM לא יסנכרן אוטומטית ולא יפעיל את הקריאה החוזרת onRegistered() בהפעלה. מומלץ מאוד להפעיל מחדש את ההפעלה האוטומטית אחרי שניתנות הרשאות לשליחת התראות. איך מפעילים מחדש את ההפעלה האוטומטית

אם ההפעלה האוטומטית חייבת להישאר מושבתת, צריך להפעיל את FirebaseMessaging.getInstance().register() בזמן הפעלת האפליקציה כדי להפעיל את הרישום ואת מסירת ה-FID באמצעות פונקציית ה-callback‏ onRegistered(). אפשר לבצע את הקריאה הזו בשיטה onCreate() של Activity הראשי.

Kotlin

  // Trigger manual registration if auto-initialization is turned off.
  // Consider calling this every time the app starts to guarantee sync status.
  FirebaseMessaging.getInstance().register()
      .addOnCompleteListener(this) { task ->
        if (!task.isSuccessful()) {
          // Registration failed. Consider retrying the registration with exponential backoff.
          Log.w(TAG, "Failed to register with Firebase Cloud Messaging", task.exception)
        }
        // Success! The Firebase Installation ID can be used to target messages to this app
        // instance and will be delivered asynchronously to your `onRegistered()` callback.
      }
    

Java

  // Trigger manual registration if auto-initialization is turned off.
  // Consider calling this every time the app starts to guarantee sync status.
  FirebaseMessaging.getInstance().register()
      .addOnCompleteListener(task -> {
        if (!task.isSuccessful()) {
          // Registration failed. Consider retrying the registration with exponential backoff.
          Log.w(TAG, "Failed to register with Firebase Cloud Messaging", task.exception)
        }
        // Success! The Firebase Installation ID can be used to target messages to this app
        // instance and will be delivered asynchronously to your `onRegistered()` callback.
      });
    

גישה לטוקן הרישום FCM (יצא משימוש)

בפעם הראשונה שמפעילים את האפליקציה, ה-SDK של FCM יוצר אסימון רישום למכונה של אפליקציית הלקוח. אם רוצים לטרגט מופעים בודדים של אפליקציות או ליצור קבוצות מכשירים, צריך לגשת לאסימון הזה על ידי הרחבה של FirebaseMessagingService ושינוי של onNewToken. יכול להיות שהטוקן יוחלף אחרי ההפעלה הראשונית, ולכן מומלץ מאוד לאחזר את טוקן הרישום המעודכן האחרון.

יכול להיות שהאסימון לרישום ישתנה במקרים הבאים:

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

אחזור של אסימון הרישום הנוכחי

כשצריך לאחזר את הטוקן הנוכחי, קוראים ל- FirebaseMessaging.getInstance().getToken():

Kotlin

FirebaseMessaging.getInstance().token.addOnCompleteListener(OnCompleteListener { task ->
    if (!task.isSuccessful) {
        Log.w(TAG, "Fetching FCM registration token failed", task.exception)
        return@OnCompleteListener
    }

    // Get new FCM registration token
    val token = task.result

    // Log and toast
    val msg = getString(R.string.msg_token_fmt, token)
    Log.d(TAG, msg)
    Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()
})

Java

FirebaseMessaging.getInstance().getToken()
    .addOnCompleteListener(new OnCompleteListener<String>() {
        @Override
        public void onComplete(@NonNull Task<String> task) {
          if (!task.isSuccessful()) {
            Log.w(TAG, "Fetching FCM registration token failed", task.getException());
            return;
          }

          // Get new FCM registration token
          String token = task.getResult();

          // Log and toast
          String msg = getString(R.string.msg_token_fmt, token);
          Log.d(TAG, msg);
          Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
        }
    });

מעקב אחר יצירת טוקנים

הפונקציה onNewToken callback מופעלת בכל פעם שנוצר אסימון חדש.

Kotlin

/**
 * Called if the FCM registration token is updated. This may occur if the security of
 * the previous token had been compromised. Note that this is called when the
 * FCM registration token is initially generated so this is where you would retrieve the token.
 */
override fun onNewToken(token: String) {
    Log.d(TAG, "Refreshed token: $token")

    // If you want to send messages to this application instance or
    // manage this apps subscriptions on the server side, send the
    // FCM registration token to your app server.
    sendRegistrationToServer(token)
}

Java

/**
 * There are two scenarios when onNewToken is called:
 * 1) When a new token is generated on initial app startup
 * 2) Whenever an existing token is changed
 * Under #2, there are three scenarios when the existing token is changed:
 * A) App is restored to a new device
 * B) User uninstalls/reinstalls the app
 * C) User clears app data
 */
@Override
public void onNewToken(@NonNull String token) {
    Log.d(TAG, "Refreshed token: " + token);

    // If you want to send messages to this application instance or
    // manage this apps subscriptions on the server side, send the
    // FCM registration token to your app server.
    sendRegistrationToServer(token);
}

אחרי שמקבלים את האסימון, אפשר לשלוח אותו לשרת האפליקציה ולאחסן אותו בשיטה המועדפת.

איך בודקים אם יש עדכונים ל-Google Play Services

באפליקציות שמסתמכות על Play Services SDK, תמיד צריך לבדוק אם במכשיר יש קובץ APK תואם של Google Play Services לפני שניגשים לתכונות של Google Play Services. מידע נוסף זמין במאמר בנושא הגדרה של Google Play Services. מומלץ לעשות את זה בשני מקומות: ב-method onCreate() של הפעילות הראשית וב-method onResume() שלה. הבדיקה ב-onCreate() מוודאת שאי אפשר להשתמש באפליקציה בלי בדיקה מוצלחת. הבדיקה ב-onResume() מוודאת שאם המשתמש חוזר לאפליקציה שפועלת בדרך אחרת, למשל באמצעות הכפתור "הקודם", הבדיקה עדיין מתבצעת.

אם במכשיר אין גרסה תואמת של Google Play Services, האפליקציה יכולה להפעיל את GoogleApiAvailability.makeGooglePlayServicesAvailable() כדי לאפשר למשתמשים להוריד את Google Play Services מחנות Play.

מניעת הפעלה אוטומטית

כשנוצר רישום של FCM, הספרייה מעלה את המזהה ואת נתוני ההגדרות ל-Firebase. אם אתם מעדיפים למנוע רישום אוטומטי, אתם צריכים להוסיף את ערכי המטא-נתונים האלה אל AndroidManifest.xml כדי להשבית את איסוף הנתונים ב-Analytics ואת ההפעלה האוטומטית של FCM (אתם צריכים להשבית את שניהם):

<meta-data
    android:name="firebase_messaging_auto_init_enabled"
    android:value="false" />
<meta-data
    android:name="firebase_analytics_collection_enabled"
    android:value="false" />

הפעלה מחדש של ההפעלה האוטומטית

כדי להפעיל מחדש את ההפעלה האוטומטית של FCM, מבצעים קריאה בזמן ריצה:

Kotlin

Firebase.messaging.isAutoInitEnabled = true

Java

FirebaseMessaging.getInstance().setAutoInitEnabled(true);

כדי להפעיל מחדש את האיסוף של Analytics, צריך להפעיל את השיטה setAnalyticsCollectionEnabled() של המחלקה FirebaseAnalytics. לדוגמה:

setAnalyticsCollectionEnabled(true);

אחרי שמגדירים את הערכים האלה, הם נשמרים גם כשמפעילים מחדש את האפליקציה.

שליחת הודעה

כדי לוודא שהלקוח שלכם ב-Android מוגדר בצורה נכונה, אתם יכולים לשלוח הודעת בדיקה באמצעות ההוראות הבאות:

  1. מתקינים ומפעילים את האפליקציה במכשיר היעד.

  2. מוודאים שהאפליקציה פועלת ברקע במכשיר.

  3. במסוף Firebase, עוברים אל DevOps & Engagement‏ > Messaging.

  4. יוצרים קמפיין.

    • אם זו ההודעה הראשונה שלכם:

      1. לוחצים על יצירת הקמפיין הראשון.

      2. בוחרים באפשרות Firebase Notification messages (הודעות התראה של Firebase) ואז באפשרות Create (יצירה).

    • אם כבר יצרתם קמפיינים בעבר:

      1. בכרטיסייה קמפיינים, לוחצים על קמפיין חדש.

      2. לוחצים על התראות.

  5. מזינים את הטקסט של ההודעה. כל שאר השדות הם אופציונליים.

  6. בחלונית השמאלית, לוחצים על שליחת הודעת בדיקה.

  7. בשדה Add an FCM registration token, מזינים את אסימון הרישום שקיבלתם בקטע הקודם במדריך הזה.

  8. לוחצים על בדיקה.

מכשיר הלקוח המיועד, כשהאפליקציה פועלת ברקע, צריך לקבל את ההתראה.

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

השלבים הבאים

אחרי שתסיימו את שלבי ההגדרה, תוכלו להשתמש ב-FCM ב-Android באחת מהדרכים הבאות: