在 Android 裝置上設定 Firebase 雲端通訊用戶端應用程式

FCM 用戶端必須使用搭載 Android 4.4 以上版本的裝置 且已安裝 Google Play 商店應用程式 透過 Google API 執行 Android 4.4 請注意,您只能透過 Google Play 商店。

設定 SDK

這個部分涵蓋您已啟用的 還有應用程式適用的其他 Firebase 功能 如果您尚未將 Firebase 新增至 Android 專案,請先完成這項操作。

編輯應用程式資訊清單

請在應用程式的資訊清單中加入以下內容:

  • 擴充 FirebaseMessagingService 的服務。以下為必要步驟 例如,除了接收應用程式通知外,也想執行任何訊息處理 背景工作。如要在前景執行的應用程式中接收通知,請執行下列操作: 資料酬載、傳送上游訊息等等,您必須擴充此 課程中也會快速介紹 Memorystore 這是 Google Cloud 的全代管 Redis 服務
  • <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 設為通知管道物件的 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 的應用程式 通知。

根據預設,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 向使用者說明 使用者授予 app 後即可發布通知。這個 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+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 服務 APK 存取 Google Play 服務功能建議在 兩處:主要活動的 onCreate() 方法,以及 onResume() 方法。onCreate() 檢查可確保應用程式 必須經過成功檢查才能使用檢查 onResume() 可確保 如果使用者透過其他方式 (例如 按一下返回按鈕,檢查仍在執行。

如果裝置沒有相容的 Google Play 服務版本,應用程式可以呼叫 GoogleApiAvailability.makeGooglePlayServicesAvailable() 讓使用者從 Play 商店下載 Google 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