本快速入門導覽課程說明如何在行動和網頁用戶端應用程式中設定 Firebase Cloud Messaging,以便穩定傳送訊息。如果是伺服器環境,請參閱「您的伺服器環境和 FCM」。
開始使用 Firebase Cloud Messaging 和 Android
FCM 用戶端需要搭載 Android 6.0 以上版本,且已安裝 Google Play 商店應用程式的裝置,或是以 Google API 執行 Android 6.0 的模擬器。請注意,您不一定要透過 Google Play 商店部署 Android 應用程式。
設定 SDK
如果您尚未將 Firebase 新增至 Android 專案,請先新增。
為獲得最佳 FCM 體驗,強烈建議您在專案中啟用 Google Analytics。Google Analytics 是FCM訊息傳送報表的必要條件。
編輯應用程式資訊清單
在應用程式的資訊清單中新增下列內容:
- 擴充
FirebaseMessagingService的服務。如果您想在應用程式於背景執行時,接收通知以外的訊息,就必須執行這項操作。如要在前景應用程式中接收通知、接收資料酬載等,您必須擴充這項服務。 - (選用) 應用程式元件中的中繼資料元素,可設定預設通知圖示和顏色。如果傳入的訊息未明確設定圖示或顏色,Android 就會使用這些值。
- (選用) Android 8.0 (API 級別 26) 以上版本支援
通知管道,建議您使用這項功能。FCM 提供預設通知管道,並採用基本設定。如要建立及使用自己的預設管道,請將
default_notification_channel_id設為通知管道物件的 ID,如圖所示;每當傳入的訊息未明確設定通知管道時,FCM 就會使用這個值。詳情請參閱「 管理通知管道」。
<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" />
<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通知功能,都會受到影響。
根據預設,FCM SDK (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); } } }
一般來說,您應顯示使用者介面,向使用者說明如果授予應用程式發布通知的權限,將啟用哪些功能。這個 UI 應提供同意或拒絕選項,例如「確定」和「不用了」按鈕。如果使用者選取「確定」,請直接要求權限。 如果使用者選取「不用了,謝謝」,請允許使用者在不接收通知的情況下繼續。
如要進一步瞭解應用程式何時應向使用者要求 POST_NOTIFICATIONS 權限,請參閱「通知執行階段權限」一文中的最佳做法。
目標為 Android 12L (API 級別 32) 以下版本的應用程式通知權限
只要應用程式處於前景,Android 就會在應用程式首次建立通知管道時,自動要求使用者授予權限。不過,建立管道和要求權限的時間點有重要注意事項:
- 如果應用程式在背景執行時建立第一個通知管道 (FCM SDK 在收到 FCM 通知時會這麼做),Android 不會允許顯示通知,也不會提示使用者提供通知權限,直到下次開啟應用程式時才會提示。也就是說,如果使用者在開啟應用程式並接受權限前收到通知,這些通知就會遺失。
- 強烈建議您更新應用程式,指定 Android 13 以上版本,以便利用平台 API 要求權限。如果無法這麼做,應用程式應先建立通知管道,再傳送任何通知給應用程式,以便觸發通知權限對話方塊,確保不會遺失任何通知。詳情請參閱通知權限最佳做法。
選用步驟:移除 POST_NOTIFICATIONS 權限
根據預設,FCM SDK 會包含 POST_NOTIFICATIONS 權限。
如果您的應用程式未使用通知訊息 (無論是透過 FCM 通知、其他 SDK,還是直接由應用程式發布),且您不希望應用程式包含這項權限,可以使用資訊清單合併工具的 remove 標記移除權限。請注意,移除這項權限會禁止顯示所有通知,而不只是 FCM 通知。在應用程式的資訊清單檔案中新增下列內容:
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" tools:node="remove"/>
存取裝置註冊權杖
應用程式首次啟動時,FCM SDK 會為用戶端應用程式例項產生註冊權杖。如要指定單一裝置或建立裝置群組,您需要擴充
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 回呼。
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 服務
如果應用程式使用 Play 服務 SDK,請務必先檢查裝置是否安裝相容的 Google Play 服務 APK,再存取 Google Play 服務功能。詳情請參閱「設定 Google Play 服務」。建議您在兩個位置執行這項操作:主要活動的 onCreate() 方法和 onResume() 方法。這項檢查可確保應用程式必須通過檢查才能使用。onCreate()onResume() 中的檢查可確保使用者透過其他方式 (例如返回按鈕) 返回執行中的應用程式時,系統仍會執行檢查。
如果裝置沒有相容版本的 Google Play 服務,應用程式可以呼叫 GoogleApiAvailability.makeGooglePlayServicesAvailable(),讓使用者從 Play 商店下載 Google Play 服務。
防止自動初始化
產生 FCM 註冊權杖時,程式庫會將 ID 和設定資料上傳至 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
Firebase.messaging.isAutoInitEnabled = true
Java
FirebaseMessaging.getInstance().setAutoInitEnabled(true);
如要重新啟用 Analytics 收集功能,請呼叫 FirebaseAnalytics 類別的 setAnalyticsCollectionEnabled() 方法。例如:
setAnalyticsCollectionEnabled(true);
設定後,這些值會在應用程式重新啟動時保留。
傳送通知訊息
如要確認 Android 用戶端設定是否正確,請按照下列操作說明傳送測試通知訊息:
- 在目標裝置上安裝並執行應用程式。
- 確認裝置上的應用程式在背景執行。
- 在 Firebase 控制台中,開啟「Messaging」頁面。
- 如果是第一次傳送訊息,請依序選取「建立第一個廣告活動」、「Firebase 通知訊息」和「建立」。
- 否則,請在「廣告活動」分頁中選取「新增廣告活動」,然後選取「通知」。
- 輸入訊息文字。其他欄位則為選填。
- 在右側窗格中選取「傳送測試訊息」。
- 在標示為「新增 FCM 註冊權杖」的欄位中,輸入您在本指南先前章節中取得的註冊權杖。
- 選取「測試」。
目標用戶端裝置應會收到通知,且應用程式必須在背景執行。
如要進一步瞭解訊息傳送至應用程式的情形,請參閱FCM報表資訊主頁,其中會記錄在 Apple 和 Android 裝置上傳送及開啟的訊息數量,以及 Android 應用程式的曝光次數 (使用者看到的通知) 資料。
後續步驟
完成設定步驟後,您可以選擇下列幾種方式,繼續使用 Android 版 FCM: