在 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