Powiadomienia Firebase działają inaczej w zależności od tego, czy aplikacja odbierająca jest na pierwszym planie, czy w tle. Jeśli chcesz, aby aplikacje na pierwszym planie otrzymywały wiadomości z powiadomieniami lub wiadomości z danymi, musisz napisać kod do obsługi wywołania zwrotnego onMessageReceived
.
Wyjaśnienie różnicy między powiadomieniami a wiadomościami z danymi znajdziesz w sekcji Typy wiadomości.
Obsługa wiadomości
Aby otrzymywać wiadomości, użyj usługi, która rozszerza
FirebaseMessagingService
.
Usługa powinna zastępować wywołania zwrotne onMessageReceived
i onDeletedMessages
.
Okres na obsługę wiadomości może być krótszy niż 20 sekund w zależności od opóźnień przed wywołaniem funkcji onMessageReceived
, w tym opóźnień systemu operacyjnego, czasu uruchamiania aplikacji, zablokowania głównego wątku przez inne operacje lub zbyt długiego czasu trwania poprzednich wywołań funkcji onMessageReceived
. Po tym czasie różne zachowania systemu operacyjnego, takie jak zamykanie procesów w Androidzie czy
limity wykonywania w tle w Androidzie O, mogą utrudniać dokończenie pracy.
onMessageReceived
jest dostępny w przypadku większości typów wiadomości, z wyjątkiem:
-
Wiadomości z powiadomieniami dostarczane, gdy aplikacja działa w tle. W takim przypadku powiadomienie jest dostarczane do obszaru powiadomień urządzenia. Gdy użytkownik kliknie powiadomienie, domyślnie otworzy się menu z aplikacjami.
-
Wiadomości z ładunkiem powiadomienia i danych, gdy są odbierane w tle. W takim przypadku powiadomienie jest dostarczane do zasobnika systemowego urządzenia, a ładunek danych jest dostarczany w dodatkach do intencji aktywności programu uruchamiającego.
W skrócie:
Stan aplikacji | Powiadomienie | Dane | Oba rodzaje |
---|---|---|---|
Pierwszy plan | onMessageReceived |
onMessageReceived |
onMessageReceived |
Tło | Obszar powiadomień | onMessageReceived |
Powiadomienie: zasobnik systemowy Dane: w dodatkach do intencji. |
Edytowanie pliku manifestu aplikacji
Aby używać FirebaseMessagingService
, musisz dodać do pliku manifestu aplikacji następujące elementy:
<service android:name=".java.MyFirebaseMessagingService" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service>
Zalecamy też ustawienie wartości domyślnych, aby dostosować wygląd powiadomień. Możesz określić niestandardową ikonę domyślną i niestandardowy kolor domyślny, które będą stosowane, gdy w ładunku powiadomienia nie będą ustawione równoważne wartości.
Dodaj te wiersze w tagu
application
, aby ustawić niestandardową ikonę domyślną i niestandardowy kolor:
<!-- 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 wyświetla niestandardową ikonę domyślną dla
- Wszystkie wiadomości z powiadomieniami wysyłane z edytora powiadomień.
- Każda wiadomość powiadomienia, która nie zawiera ikony w ładunku powiadomienia.
Android używa niestandardowego koloru domyślnego w przypadku
- Wszystkie wiadomości z powiadomieniami wysyłane z edytora powiadomień.
- Każda wiadomość z powiadomieniem, która nie zawiera w ładunku powiadomienia wyraźnego ustawienia koloru.
Jeśli nie ustawiono niestandardowej ikony domyślnej ani ikony w ładunku powiadomienia, Android wyświetla ikonę aplikacji w kolorze białym.
Zastąp onMessageReceived
Zastępując metodę FirebaseMessagingService.onMessageReceived
, możesz wykonywać działania na podstawie otrzymanego obiektu RemoteMessage i pobierać dane wiadomości:
Kotlin
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. }
Zastąp onDeletedMessages
W niektórych sytuacjach usługa FCM może nie dostarczyć wiadomości. Dzieje się tak, gdy w momencie połączenia na urządzeniu jest zbyt wiele oczekujących wiadomości (>100) dla Twojej aplikacji lub gdy urządzenie nie łączyło się z FCM od ponad miesiąca. W takich przypadkach możesz otrzymać wywołanie zwrotne na adres FirebaseMessagingService.onDeletedMessages()
. Gdy instancja aplikacji otrzyma to wywołanie zwrotne, powinna przeprowadzić pełną synchronizację z serwerem aplikacji. Jeśli w ciągu ostatnich 4 tygodni nie wysłano z tego urządzenia wiadomości do aplikacji, FCM nie zadzwoni do onDeletedMessages()
.
Obsługa wiadomości z powiadomieniami w aplikacji działającej w tle
Gdy aplikacja działa w tle, Android kieruje wiadomości z powiadomieniami do obszaru powiadomień. Gdy użytkownik kliknie powiadomienie, domyślnie otworzy się menu z aplikacjami.
Dotyczy to wiadomości zawierających zarówno powiadomienia, jak i ładunek danych (oraz wszystkich wiadomości wysyłanych z konsoli powiadomień). W takich przypadkach powiadomienie jest dostarczane do zasobnika systemowego urządzenia, a ładunek danych jest dostarczany w dodatkach do intencji aktywności programu uruchamiającego.
Aby uzyskać informacje o dostarczaniu wiadomości do aplikacji, otwórz FCM panel raportowania, który rejestruje liczbę wysłanych i otwartych wiadomości na urządzeniach z Androidem i Apple, a także dane o „wyświetleniach” (powiadomieniach widocznych dla użytkowników) w przypadku aplikacji na Androida.
Odbieranie wiadomości FCM w trybie bezpośredniego uruchamiania
Deweloperzy, którzy chcą wysyłać wiadomości FCM do aplikacji jeszcze przed odblokowaniem urządzenia, mogą włączyć w aplikacji na Androida odbieranie wiadomości, gdy urządzenie jest w trybie bezpośredniego uruchamiania. Możesz na przykład chcieć, aby użytkownicy Twojej aplikacji otrzymywali powiadomienia o alarmie nawet na zablokowanym urządzeniu.
Podczas tworzenia tego przypadku użycia przestrzegaj ogólnych sprawdzonych metod i ograniczeń dotyczących trybu bezpośredniego uruchamiania. Szczególnie ważne jest rozważenie widoczności wiadomości włączonych w trybie bezpośredniego rozruchu. Każdy użytkownik, który ma dostęp do urządzenia, może wyświetlić te wiadomości bez podawania danych logowania.
Wymagania wstępne
- Urządzenie musi być skonfigurowane w trybie bezpośredniego uruchamiania.
- Na urządzeniu musi być zainstalowana najnowsza wersja Usług Google Play (19.0.54 lub nowsza).
- Aplikacja musi używać pakietu SDK FCM (
com.google.firebase:firebase-messaging
), aby otrzymywać wiadomości FCM.
Włącz obsługę wiadomości w trybie bezpośredniego uruchamiania w aplikacji
W pliku Gradle na poziomie aplikacji dodaj zależność od biblioteki obsługi bezpośredniego uruchamiania FCM:
implementation 'com.google.firebase:firebase-messaging-directboot:20.2.0'
Spraw, aby aplikacja
FirebaseMessagingService
obsługiwała bezpośrednie uruchamianie, dodając atrybutandroid:directBootAware="true"
w pliku manifestu aplikacji:<service android:name=".java.MyFirebaseMessagingService" android:exported="false" android:directBootAware="true"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service>
Ważne jest, aby FirebaseMessagingService
działał w trybie bezpośredniego uruchamiania. Sprawdź, czy spełnione są te wymagania:
- Usługa nie powinna mieć dostępu do pamięci chronionej przez dane logowania, gdy działa w trybie bezpośredniego uruchamiania.
- Usługa nie powinna próbować używać komponentów, takich jak
Activities
,BroadcastReceivers
lub innychServices
, które nie są oznaczone jako obsługujące bezpośrednie uruchamianie, gdy działa w trybie bezpośredniego uruchamiania. - Żadne biblioteki używane przez usługę nie mogą też uzyskiwać dostępu do pamięci chronionej przez dane logowania ani wywoływać komponentów nieobsługujących trybu bezpośredniego rozruchu, gdy usługa działa w tym trybie. Oznacza to, że wszystkie biblioteki używane przez aplikację, które są wywoływane z usługi, muszą być zgodne z bezpośrednim uruchamianiem lub aplikacja musi sprawdzać, czy działa w trybie bezpośredniego uruchamiania, i nie wywoływać ich w tym trybie. Na przykład pakiety SDK Firebase działają w trybie bezpośredniego uruchamiania (można je uwzględnić w aplikacji bez powodowania jej awarii w tym trybie), ale wiele interfejsów API Firebase nie obsługuje wywoływania w trybie bezpośredniego uruchamiania.
- Jeśli aplikacja korzysta z niestandardowego
Application
, musi on też obsługiwać bezpośrednie uruchamianie (w trybie bezpośredniego uruchamiania nie ma dostępu do pamięci chronionej hasłem).Application
Wskazówki dotyczące wysyłania wiadomości na urządzenia w trybie bezpośredniego rozruchu znajdziesz w artykule Wysyłanie wiadomości na urządzenia z włączonym trybem bezpośredniego rozruchu.