Google is committed to advancing racial equity for Black communities. See how.
本頁面由 Cloud Translation API 翻譯而成。
Switch to English

在Android應用中接收消息

Firebase通知的行為根據接收應用程序的前/後狀態而有所不同。如果希望前台的應用程序接收通知消息或數據消息,則需要編寫代碼來處理onMessageReceived回調。有關通知消息和數據消息之間差異的說明,請參閱消息類型

處理消息

要接收消息,請使用擴展FirebaseMessagingService的服務。您的服務應覆蓋onMessageReceivedonDeletedMessages回調。它應該在收到郵件後20秒內處理任何消息(在Android Marshmallow中為10秒)。時間窗口可能會更短,具體取決於調用onMessageReceived之前發生的操作系統延遲。在那之後,各種操作系統行為(例如Android O的後台執行限制)可能會干擾您完成工作的能力。有關更多信息,請參見有關消息優先級的概述。

大多數消息類型都提供onMessageReceived ,但以下情況除外:

  • 當您的應用程序處於後台時,會發送通知消息。在這種情況下,通知將傳遞到設備的系統托盤。默認情況下,用戶點擊通知會打開應用啟動器。

  • 在後台收到的同時具有通知和數據有效負載的消息。在這種情況下,通知將傳遞到設備的系統托盤,而數據有效載荷將在啟動器活動的意圖之外傳遞。

綜上所述:

應用狀態通知數據
前景onMessageReceived onMessageReceived onMessageReceived
背景系統托盤onMessageReceived通知:系統托盤
數據:意圖之外。
有關消息類型的更多信息,請參閱通知和數據消息

編輯應用清單

要使用FirebaseMessagingService ,您需要在應用清單中添加以下內容:

<service
    android:name=".java.MyFirebaseMessagingService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

另外,建議您設置默認值以自定義通知的外觀。您可以指定在通知有效負載中未設置等效值時將應用的自定義默認圖標和自定義默認顏色。

application標記內添加以下行以設置自定義默認圖標和自定義顏色:

<!-- 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將顯示以下內容的自定義默認圖標:

  • Notifications作曲家發送的所有通知消息。
  • 任何未在通知有效負載中明確設置圖標的通知消息。

Android將自定義默認顏色用於

  • Notifications作曲家發送的所有通知消息。
  • 任何未在通知有效負載中明確設置顏色的通知消息。

如果未設置自定義默認圖標,並且在通知有效負載中也未設置圖標,則Android將以白色顯示應用程序圖標。

覆蓋onMessageReceived

通過重寫方法FirebaseMessagingService.onMessageReceived ,可以基於接收到的RemoteMessage對象執行操作並獲取消息數據:

爪哇

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    // ...

    // TODO(developer): Handle FCM messages here.
    // Not getting messages here? See why this may be: https://goo.gl/39bRNJ
    Log.d(TAG, "From: " + remoteMessage.getFrom());

    // Check if message contains a data payload.
    if (remoteMessage.getData().size() > 0) {
        Log.d(TAG, "Message data payload: " + remoteMessage.getData());

        if (/* Check if data needs to be processed by long running job */ true) {
            // For long-running tasks (10 seconds or more) use WorkManager.
            scheduleJob();
        } else {
            // Handle message within 10 seconds
            handleNow();
        }

    }

    // Check if message contains a notification payload.
    if (remoteMessage.getNotification() != null) {
        Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
    }

    // Also if you intend on generating your own notifications as a result of a received FCM
    // message, here is where that should be initiated. See sendNotification method below.
}

Kotlin + KTX

override fun onMessageReceived(remoteMessage: RemoteMessage) {
    // ...

    // TODO(developer): Handle FCM messages here.
    // Not getting messages here? See why this may be: https://goo.gl/39bRNJ
    Log.d(TAG, "From: ${remoteMessage.from}")

    // Check if message contains a data payload.
    if (remoteMessage.data.isNotEmpty()) {
        Log.d(TAG, "Message data payload: ${remoteMessage.data}")

        if (/* Check if data needs to be processed by long running job */ true) {
            // For long-running tasks (10 seconds or more) use WorkManager.
            scheduleJob()
        } else {
            // Handle message within 10 seconds
            handleNow()
        }
    }

    // Check if message contains a notification payload.
    remoteMessage.notification?.let {
        Log.d(TAG, "Message Notification Body: ${it.body}")
    }

    // Also if you intend on generating your own notifications as a result of a received FCM
    // message, here is where that should be initiated. See sendNotification method below.
}

覆蓋onDeletedMessages

在某些情況下,FCM可能不會傳遞消息。當特定應用在連接時在您的應用上有太多待處理消息(> 100),或者該設備在一個多月內未連接到FCM時,就會發生這種情況。在這些情況下,您可能會收到FirebaseMessagingService.onDeletedMessages()的回調,當應用程序實例收到此回調時,它應與您的應用程序服務器執行完全同步。如果您在過去4週內未onDeletedMessages()設備上的應用發送消息,則FCM不會調用onDeletedMessages()

在後台應用程序中處理通知消息

當您的應用程序在後台運行時,Android會將通知消息定向到系統任務欄。默認情況下,用戶點擊通知會打開應用啟動器。

這包括同時包含通知和數據有效負載的消息(以及從Notifications控制台發送的所有消息)。在這些情況下,通知將傳遞到設備的系統托盤,而數據有效載荷將在啟動器活動的意圖之外傳遞。

要深入了解將消息傳遞到您的應用程序,請參閱FCM報告儀表板,該儀表板記錄了iOS和Android設備上已發送和打開的消息數,以及Android應用程序的“展示”(用戶看到的通知)數據。

後台受限應用(Android P或更高版本)

FCM可能不會將消息傳遞到用戶已被後台限制的應用程序(例如通過:設置->應用程序和通知-> [應用程序名稱]->電池)。將您的應用程序從後台限制中刪除後,將像以前一樣向該應用程序發送新消息。為了防止消息丟失和其他背景限制影響,請確保避免Android生命週期措施列出的不良行為。這些行為可能導致Android設備向用戶推薦您的應用受後台限制。您的應用可以使用isBackgroundRestricted()檢查它是否受後台限制。

在直接啟動模式下接收FCM消息

想要在設備未鎖定之前就向應用發送FCM消息的開發人員,可以使Android應用在設備處於直接啟動模式時接收消息。例如,您可能希望您的應用程序用戶即使在鎖定的設備上也能接收警報通知。

建立此用例時,請遵循直接引導模式的一般最佳實踐和限制。考慮啟用直接引導的消息的可見性尤為重要。有權訪問該設備的任何用戶都可以查看這些消息,而無需輸入用戶憑據。

先決條件

  • 必須將設備設置為直接啟動模式。
  • 該設備必須安裝了最新版本的Google Play服務(19.0.54或更高版本)。
  • 該應用必須使用FCM SDK( com.google.firebase:firebase-messaging )才能接收FCM消息。

在您的應用中啟用直接啟動模式消息處理

  1. 在應用程序級別的Gradle文件中,添加對FCM直接啟動支持庫的依賴項:

    implementation 'com.google.firebase:firebase-messaging-directboot:20.2.0'
    
  2. 通過在應用清單中添加android:directBootAware="true"屬性,使應用的FirebaseMessagingService直接啟動可android:directBootAware="true"

    <service
        android:name=".java.MyFirebaseMessagingService"
        android:exported="false"
        android:directBootAware="true">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
    

確保此FirebaseMessagingService可以在直接啟動模式下運行很重要。檢查以下要求:

  • 在直接引導模式下運行時,該服務不應訪問受憑據保護的存儲。
  • 該服務不應嘗試使用在直接啟動模式下運行時未標記為直接啟動感知的組件,例如ActivitiesBroadcastReceivers或其他Services
  • 在直接引導模式下運行時,該服務使用的任何庫也不得訪問受憑證保護的存儲,也不得調用非directBootAware組件。這意味著應用程序使用的從服務調用的任何庫要么需要直接引導感知,要么應用程序需要檢查其是否在直接引導模式下運行,而不是在該模式下調用它們。例如,Firebase SDK可以直接啟動(它們可以包含在應用程序中,而不會在直接啟動模式下崩潰),但是許多Firebase API不支持在直接啟動模式下調用。
  • 如果應用程序使用的是自定義Application ,則該Application還需要支持直接引導(在直接引導模式下無法訪問受憑證保護的存儲)。

有關在直接引導模式下向設備發送消息的指導,請參閱發送已啟用直接引導的消息