FCM 用戶端需要搭載 Android 5.0 以上版本,且已安裝 Google Play 商店應用程式的裝置,或是搭載 Android 5.0 並使用 Google API 的模擬器。請注意,你不限於透過 Google Play 商店部署 Android 應用程式。
設定 SDK
本節涵蓋如果您已為應用程式啟用其他 Firebase 功能,先前已完成的工作。如果您尚未將 Firebase 新增至 Android 專案,請先完成此步驟。
編輯應用程式資訊清單
在應用程式資訊清單中新增以下內容:
- 擴充
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+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); } } }
一般來說,您應顯示使用者介面,向使用者說明授予應用程式發布通知權限後,可啟用的功能。這個 UI 應為使用者提供同意或拒絕的選項,例如「OK」和「No 這個選項」按鈕。如果使用者選取「確定」,請直接要求權限。如果使用者選取「不用了,謝謝」,請允許使用者繼續操作,但不顯示通知。
如要進一步瞭解應用程式應在何時向使用者要求 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+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(); } });
監控權杖產生作業
每當產生新的權杖,就會觸發 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 服務
依賴 Play 服務 SDK 的應用程式在存取 Google Play 服務功能前,應一律檢查裝置是否有相容的 Google Play 服務 APK。建議您在兩個地方執行此操作:在主要活動的 onCreate()
方法和其 onResume()
方法中執行這項操作。onCreate()
中的檢查可確保在未成功檢查的情況下,使用者無法使用應用程式。onResume()
中的檢查可確保使用者透過其他方式 (例如透過返回按鈕) 返回執行中的應用程式時,仍會執行檢查。
如果裝置不具備相容的 Google Play 服務版本,應用程式可以呼叫 GoogleApiAvailability.makeGooglePlayServicesAvailable()
,讓使用者從 Play 商店下載 Google Play 服務。
防止自動初始化
產生 FCM 註冊權杖後,程式庫會將 ID 和設定資料上傳至 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+KTX
Firebase.messaging.isAutoInitEnabled = true
Java
FirebaseMessaging.getInstance().setAutoInitEnabled(true);
如要重新啟用 Analytics 收集功能,請呼叫 FirebaseAnalytics
類別的 setAnalyticsCollectionEnabled()
方法。例如:
setAnalyticsCollectionEnabled(true);
設定後,這些值會在應用程式重新啟動時保留。
後續步驟
設定完用戶端應用程式後,您就可以開始使用 通知編寫工具傳送下游訊息。快速入門範例會示範這項功能,您可以下載、執行及查看該範例。
如要為應用程式新增其他更進階的行為,您可以宣告意圖篩選器,並實作活動來回應傳入的訊息。如需詳細資訊,請參閱從應用程式伺服器傳送訊息的指南:
請注意,如要充分運用這些功能,您需要伺服器導入作業和伺服器通訊協定 (HTTP 或 XMPP),或是Admin SDK 的導入作業。