לקוחות FCM דורשים מכשירים עם Android מגרסה 5.0 ואילך, שבהם מותקנת גם אפליקציית חנות Play, או אמולטור עם Android מגרסה 5.0 עם ממשקי Google API. חשוב לזכור שאתם לא מוגבלים לפריסה של אפליקציות ל-Android דרך חנות Google Play.
הגדרת ה-SDK
בקטע הזה מפורטות משימות שאולי כבר ביצעתם אם כבר הפעלתם תכונות אחרות של Firebase באפליקציה. אם עדיין לא עשיתם זאת, מוסיפים את Firebase לפרויקט Android.
עריכת המניפסט של האפליקציה
מוסיפים את הקוד הבא למניפסט של האפליקציה:
- שירות שמרחיב את
FirebaseMessagingService
. צריך לעשות זאת אם רוצים לבצע טיפול בהודעות מעבר לקבלת התראות באפליקציות שפועלות ברקע. כדי לקבל התראות באפליקציות שבחזית, לקבל עומס נתונים, לשלוח הודעות למקור (upstream) וכו', צריך להרחיב את השירות הזה.
<service android:name=".java.MyFirebaseMessagingService" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service>
<!-- 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" />
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+KTX
// 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); } } }
באופן כללי, כדאי להציג ממשק משתמש שבו מוסבר למשתמש אילו תכונות יופעלו אם הוא יעניק לאפליקציה הרשאות לפרסם התראות. ממשק המשתמש הזה צריך לספק למשתמשים אפשרויות לאשר או לדחות, כמו לחצנים של אישור ולא תודה. אם המשתמש בוחר באפשרות OK, מבקשים את ההרשאה ישירות. אם המשתמש בוחר באפשרות לא תודה, מאפשרים לו להמשיך בלי התראות.
במאמר הרשאה בזמן ריצה להצגת התראות מפורטות שיטות מומלצות נוספות לגבי הזמנים שבהם האפליקציה צריכה לבקש מהמשתמש את ההרשאה 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"/>
גישה לטוקן הרישום של המכשיר
בהפעלה הראשונית של האפליקציה, ה-SDK של FCM יוצר אסימון רישום למכונה של אפליקציית הלקוח. כדי לטרגט מכשירים ספציפיים או ליצור קבוצות של מכשירים, צריך לגשת לאסימון הזה על ידי הרחבה של
FirebaseMessagingService
ועקיפת onNewToken
.
בקטע הזה נסביר איך לאחזר את האסימון ואיך לעקוב אחרי השינויים באסימון. מכיוון שיכול להיות שתתבצע רוטציה של הטוקן אחרי ההפעלה הראשונית, מומלץ מאוד לאחזר את טוקן הרישום המעודכן האחרון.
אסימון הרישום עשוי להשתנות במקרים הבאים:
- האפליקציה משוחזרת במכשיר חדש
- המשתמש מסיר או מתקין מחדש את האפליקציה
- המשתמש מנקה את נתוני האפליקציה.
אחזור של טוקן הרישום הנוכחי
כשצריך לאחזר את האסימון הנוכחי, צריך להפעיל את הפונקציה
FirebaseMessaging.getInstance().getToken()
:
Kotlin+KTX
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(); } });
מעקב אחר יצירת הטוקנים
קריאת החזרה (callback) של onNewToken
מופעלת בכל פעם שנוצר טוקן חדש.
Kotlin+KTX
/** * 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. מומלץ לעשות זאת בשני מקומות: ב-method onCreate()
של הפעילות הראשית וב-method onResume()
שלה. הבדיקה ב-onCreate()
מבטיחה שלא ניתן להשתמש באפליקציה בלי בדיקה מוצלחת. הבדיקה ב-onResume()
מבטיחה שאם המשתמש יחזור לאפליקציה שפועלת באמצעים אחרים, למשל באמצעות לחצן החזרה אחורה, הבדיקה עדיין תתבצע.
אם במכשיר לא מותקנת גרסה תואמת של Google Play Services, האפליקציה יכולה להפעיל את GoogleApiAvailability.makeGooglePlayServicesAvailable()
כדי לאפשר למשתמשים להוריד את Google Play Services מחנות Play.
מניעת אתחול אוטומטי
כשיוצרים אסימון רישום מסוג FCM, הספרייה מעלה את המזהה ונתוני ההגדרה ל-Firebase. אם אתם מעדיפים למנוע יצירה אוטומטית של אסימונים, צריך להשבית את האיסוף ב-Analytics ואת האיפוס האוטומטי של FCM (צריך להשבית את שניהם) על ידי הוספת ערכי המטא-נתונים הבאים ל-AndroidManifest.xml
:
<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+KTX
Firebase.messaging.isAutoInitEnabled = true
Java
FirebaseMessaging.getInstance().setAutoInitEnabled(true);
כדי להפעיל מחדש את האיסוף ב-Analytics, צריך להפעיל את השיטה setAnalyticsCollectionEnabled()
של הכיתה FirebaseAnalytics
. לדוגמה:
setAnalyticsCollectionEnabled(true);
הערכים האלה נשארים לאחר הפעלה מחדש של האפליקציה.
השלבים הבאים
אחרי שמגדירים את אפליקציית הלקוח, אפשר להתחיל לשלוח הודעות במורד הזרם באמצעות כלי היצירה של התראות. הפונקציונליות הזו מופיעה בדוגמה למדריך למתחילים, שאפשר להוריד, להריץ ולבדוק.
כדי להוסיף לאפליקציה התנהגות מתקדמת יותר, אפשר להצהיר על מסנן כוונה ולהטמיע פעילות כדי להגיב להודעות נכנסות. פרטים נוספים זמינים במדריכים לשליחת הודעות משרת אפליקציה:
חשוב לזכור: כדי ליהנות מהתכונות האלה, תצטרכו הטמעה בשרת ואת הפרוטוקולים של השרת (HTTP או XMPP), או הטמעה של Admin SDK.