Firebase 通知的運作方式會因前景/背景而異
接收端應用程式的狀態。如果您希望前景應用程式接收
通知訊息或資料訊息時,請編寫用於處理
onMessageReceived
回呼。
如需通知與資料訊息之間的差異
請參閱「郵件類型」。
處理訊息
如要接收訊息,請使用
FirebaseMessagingService
。
您的服務應覆寫 onMessageReceived
和 onDeletedMessages
回呼函式。
郵件處理時長可能短於 20 秒,視延遲情況而定
在呼叫 onMessageReceived
之前發生,包括 OS 延遲、應用程式啟動時間、
主要執行緒遭到其他作業封鎖 (或先前的 onMessageReceived
)
通話時間過長。超過 190 天後,各種作業系統行為,如 Android 的
處理程序
終止或 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 會顯示自訂預設圖示
- 透過以下服務傳送的所有通知訊息: 通知編輯器。
- 未明確設定通知酬載中圖示的任何通知訊息。
Android 會使用自訂預設顏色
- 透過以下服務傳送的所有通知訊息: 通知編輯器。
- 未明確設定通知顏色的任何通知訊息 酬載。
如未設定自訂預設圖示,也未在通知酬載中設定圖示, Android 顯示應用程式圖示以白色顯示。
覆寫 onMessageReceived
覆寫 FirebaseMessagingService.onMessageReceived
方法後
您就能依據
RemoteMessage
物件,並取得訊息資料:
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}") // Check if data needs to be processed by long running job if (needsToBeScheduled()) { // 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. }
Java
@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. }
覆寫 onDeletedMessages
在某些情況下,FCM 可能無法傳送訊息。當系統傳送過多提案時
有 則訊息 (>100) 待審核
應用程式在連線的特定裝置上,或裝置未連線時
超過 1 個月了 FCM。在這些情況下
系統可能會回撥給 FirebaseMessagingService.onDeletedMessages()
應用程式執行個體收到此回呼時
應該能與應用程式伺服器執行完整同步。如果有沒有傳送訊息給應用程式
裝置在過去 4 週內,FCM 將不會呼叫 onDeletedMessages()
。
在背景執行應用程式中處理通知訊息
當應用程式在背景運作時,Android 會將通知訊息導向至 系統匣。使用者輕觸通知,即可開啟應用程式啟動器 預設值。
這包括包含通知和資料的訊息 酬載 (以及從通知控制台傳送的所有郵件)。 在這些情況下,通知會傳送到裝置的 系統匣,而資料酬載則會在意圖的額外項目中傳送 。
如要進一步瞭解訊息傳送至應用程式的資訊,請參閱 FCM 報表資訊主頁,當中記錄了 透過 Apple 和 Android 裝置傳送及開啟的訊息數量,以及 「曝光」資料Android 應用程式 (使用者看到的通知)。
透過直接啟動模式接收 FCM 訊息
想要傳送 FCM 訊息給應用程式的開發人員,甚至 裝置處於解鎖狀態時,Android 應用程式可在裝置中接收訊息 處於直接啟動模式例如,您可能希望應用程式的使用者 甚至在裝置鎖定時接收鬧鐘通知。
建構這個應用實例時,請觀察 直接啟動模式的最佳做法和限制。是 必須考量直接啟動功能的能見度 訊息;凡是能存取裝置的使用者都能查看這些訊息,不需要 輸入使用者憑證
事前準備
- 必須將裝置設為直接啟動模式。
- 裝置必須安裝最新版本的 Google Play 服務 (19.0.54 以上版本)。
- 應用程式必須使用 FCM SDK (
com.google.firebase:firebase-messaging
) 才能接收 FCM 訊息。
在應用程式中啟用直接啟動模式訊息處理功能
在應用程式層級的 Gradle 檔案中,新增 FCM 直接啟動支援資料庫的依附元件:
implementation 'com.google.firebase:firebase-messaging-directboot:20.2.0'
請在應用程式資訊清單中新增
android:directBootAware="true"
屬性,讓應用程式的FirebaseMessagingService
直接啟動感知特性:<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
能在直接啟動模式下執行。確認
符合下列要求:
- 服務在直接啟動模式下執行時,不應存取受憑證保護的儲存空間。
- 服務不得試圖使用
Activities
、BroadcastReceivers
、 或其他未標示為直接啟動感知的Services
。 - 這項服務使用的任何程式庫也不得存取受憑證保護的儲存空間 在直接啟動模式下執行時,呼叫非 directBootAware 元件。也就是說 從服務呼叫的應用程式使用必須具有直接啟動感知特性,或是 應用程式必須檢查它是否在直接啟動模式下執行,且沒有在該模式下呼叫應用程式。 舉例來說,Firebase SDK 支援直接啟動功能,您可以將 SDK 加到應用程式,完全不必 導致應用程式當機,但許多 Firebase API 不支援直接呼叫 啟動模式
- 如果應用程式使用自訂
Application
,則Application
也必須直接啟動 感知 (無法在直接啟動模式下存取受憑證保護的儲存空間)。
如要瞭解如何以直接啟動模式傳送訊息至裝置,請參閱 傳送可直接啟動功能的訊息。