Odbieraj wiadomości w aplikacji na Androida

Powiadomienia Firebase zachowują się inaczej w zależności od stanu pierwszego/tła aplikacji odbierającej. Jeśli chcesz, aby aplikacje na pierwszym planie otrzymywały powiadomienia lub wiadomości z danymi, musisz napisać kod obsługujący wywołanie zwrotne onMessageReceived . Aby poznać różnicę między powiadomieniami a wiadomościami z danymi, zobacz Typy wiadomości .

Obsługa wiadomości

Aby odbierać wiadomości, użyj usługi rozszerzającej FirebaseMessagingService . Twoja usługa powinna zastąpić wywołania zwrotne onMessageReceived i onDeletedMessages .

Okno czasowe na obsługę wiadomości może być krótsze niż 20 sekund w zależności od opóźnień powstałych przed wywołaniem onMessageReceived , w tym opóźnień systemu operacyjnego, czasu uruchamiania aplikacji, zablokowania głównego wątku przez inne operacje lub poprzednich wywołań onMessageReceived trwających zbyt długo. Po tym czasie różne zachowania systemu operacyjnego, takie jak zabijanie procesów w systemie Android lub limity wykonywania w tle w systemie Android O, mogą zakłócać możliwość ukończenia pracy.

onMessageReceived jest dostępny dla większości typów wiadomości, z następującymi wyjątkami:

  • Powiadomienia dostarczane, gdy aplikacja działa w tle . W takim przypadku powiadomienie jest dostarczane do zasobnika systemowego urządzenia. Dotknięcie powiadomienia przez użytkownika domyślnie otwiera program uruchamiający aplikacje.

  • Wiadomości zawierające zarówno powiadomienia, jak i dane, odbierane w tle . W takim przypadku powiadomienie jest dostarczane do zasobnika systemowego urządzenia, a ładunek danych jest dostarczany w ramach dodatków do aktywności programu uruchamiającego.

W podsumowaniu:

Stan aplikacji Powiadomienie Dane Obydwa
Pierwszoplanowy onMessageReceived onMessageReceived onMessageReceived
Tło Taca systemowa onMessageReceived Powiadomienie: zasobnik systemowy
Dane: w dodatkach intencji.
Aby uzyskać więcej informacji na temat typów wiadomości, zobacz Powiadomienia i wiadomości dotyczące danych .

Edytuj manifest aplikacji

Aby korzystać z FirebaseMessagingService , musisz dodać następujące informacje w manifeście aplikacji:

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

Zaleca się także ustawienie wartości domyślnych w celu dostosowania wyglądu powiadomień. Można określić niestandardową ikonę domyślną i niestandardowy domyślny kolor, które będą stosowane, gdy w ładunku powiadomienia nie zostaną ustawione równoważne wartości.

Dodaj te linie wewnątrz znacznika application , aby ustawić niestandardową domyślną ikonę 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ą domyślną ikonę dla

Android używa niestandardowego domyślnego koloru dla

Jeśli nie ustawiono żadnej niestandardowej ikony domyślnej ani w ładunku powiadomienia, system Android wyświetla ikonę aplikacji renderowaną na biało.

Zastąp onMessageReceived

Nadpisując metodę FirebaseMessagingService.onMessageReceived , możesz wykonać akcje na podstawie odebranego obiektu RemoteMessage i uzyskać dane komunikatu:

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.
}

Zastąp onDeletedMessages

W niektórych sytuacjach FCM może nie dostarczyć wiadomości. Dzieje się tak, gdy w momencie nawiązania połączenia na określonym urządzeniu znajduje się zbyt wiele wiadomości (>100) oczekujących dla Twojej aplikacji lub jeśli urządzenie nie łączyło się z FCM przez ponad miesiąc. W takich przypadkach możesz otrzymać wywołanie zwrotne do FirebaseMessagingService.onDeletedMessages() . Gdy instancja aplikacji odbierze to wywołanie zwrotne, powinna przeprowadzić pełną synchronizację z serwerem aplikacji. Jeśli w ciągu ostatnich 4 tygodni nie wysłałeś wiadomości do aplikacji na tym urządzeniu, FCM nie wywoła onDeletedMessages() .

Obsługuj powiadomienia w aplikacji działającej w tle

Gdy aplikacja działa w tle, Android kieruje powiadomienia do paska zadań. Dotknięcie powiadomienia przez użytkownika domyślnie otwiera program uruchamiający aplikacje.

Obejmuje to wiadomości zawierające zarówno powiadomienia, jak i ładunek danych (oraz wszystkie wiadomości wysłane z konsoli powiadomień). W takich przypadkach powiadomienie jest dostarczane do zasobnika systemowego urządzenia, a ładunek danych jest dostarczany w ramach dodatków do Aktywności programu uruchamiającego.

Wgląd w dostarczanie wiadomości do aplikacji znajdziesz w panelu raportowania FCM , który rejestruje liczbę wiadomości wysłanych i otwartych na urządzeniach Apple i Android, wraz z danymi dotyczącymi „wyświetleń” (powiadomień widocznych przez użytkowników) w przypadku aplikacji na Androida.

Odbieraj komunikaty FCM w trybie bezpośredniego rozruchu

Programiści, którzy chcą wysyłać wiadomości FCM do aplikacji jeszcze przed odblokowaniem urządzenia, mogą włączyć aplikację na Androida, aby odbierała wiadomości, gdy urządzenie znajduje się w trybie rozruchu bezpośredniego. Na przykład możesz chcieć, aby użytkownicy Twojej aplikacji otrzymywali powiadomienia o alarmach nawet na zablokowanym urządzeniu.

Tworząc ten przypadek użycia, należy przestrzegać ogólnych najlepszych praktyk i ograniczeń dotyczących trybu rozruchu bezpośredniego . Szczególnie ważne jest rozważenie widoczności komunikatów umożliwiających bezpośredni rozruch; każdy użytkownik mający dostęp do urządzenia może przeglądać te wiadomości bez wprowadzania danych uwierzytelniających użytkownika.

Warunki wstępne

  • Urządzenie musi być skonfigurowane do trybu bezpośredniego rozruchu.
  • Na urządzeniu musi być zainstalowana najnowsza wersja usług Google Play (19.0.54 lub nowsza).
  • Aby móc odbierać wiadomości FCM, aplikacja musi korzystać z pakietu SDK FCM ( com.google.firebase:firebase-messaging ).

Włącz obsługę komunikatów w trybie bezpośredniego rozruchu w swojej aplikacji

  1. W pliku Gradle na poziomie aplikacji dodaj zależność od biblioteki obsługi bezpośredniego rozruchu FCM:

    implementation 'com.google.firebase:firebase-messaging-directboot:20.2.0'
    
  2. Włącz funkcję FirebaseMessagingService , która umożliwia bezpośrednie uruchomienie aplikacji, dodając atrybut android:directBootAware="true" w manifeście 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 upewnić się, że ta FirebaseMessagingService może działać w trybie bezpośredniego rozruchu. Sprawdź następujące wymagania:

  • Usługa nie powinna uzyskiwać dostępu do magazynu chronionego poświadczeniami podczas działania w trybie rozruchu bezpośredniego.
  • Usługa nie powinna próbować używać komponentów, takich jak Activities , BroadcastReceivers lub inne Services , które nie są oznaczone jako obsługujące rozruch bezpośredni podczas działania w trybie rozruchu bezpośredniego.
  • Żadne biblioteki używane przez usługę nie mogą również uzyskiwać dostępu do magazynu chronionego danymi uwierzytelniającymi ani wywoływać komponentów innych niż directBootAware podczas działania w trybie rozruchu bezpośredniego. Oznacza to, że wszystkie biblioteki używane przez aplikację i wywoływane z usługi będą musiały obsługiwać rozruch bezpośredni lub aplikacja będzie musiała sprawdzić, czy działa w trybie rozruchu bezpośredniego i nie wywoływać ich w tym trybie. Na przykład zestawy SDK Firebase działają z rozruchem bezpośrednim (można je dołączyć do aplikacji bez powodowania jej awarii w trybie rozruchu bezpośredniego), ale wiele interfejsów API Firebase nie obsługuje wywoływania w trybie rozruchu bezpośredniego.
  • Jeśli aplikacja korzysta z Application niestandardowej, Application będzie również musiała obsługiwać rozruch bezpośredni (brak dostępu do magazynu chronionego danymi uwierzytelniającymi w trybie rozruchu bezpośredniego).

Aby uzyskać wskazówki dotyczące wysyłania wiadomości do urządzeń w trybie rozruchu bezpośredniego, zobacz Wysyłanie wiadomości z włączonym rozruchem bezpośrednim .