Odbieranie wiadomości za pomocą Komunikacji w chmurze Firebase

Z tego przewodnika dowiesz się, jak skonfigurować Firebase Cloud Messaging w aplikacjach klienckich na urządzenia mobilne i w internecie, aby niezawodnie odbierać wiadomości.

Aby otrzymywać wiadomości, możesz użyć usługi, która rozszerza FirebaseMessagingService. Usługa powinna zastępować wywołania zwrotne onMessageReceivedonDeletedMessages. Pełny przykład znajdziesz w przykładowym projekcie szybkiego startu Komunikacji w chmurze Firebase.

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 powiadomieniem i ładunkiem danych, gdy są odbierane w tle. W takim przypadku powiadomienie jest dostarczane do zasobnika systemowego urządzenia, a ładunek danych jest dostarczany w dodatkach 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: obszar powiadomień. Dane: w dodatkach intencji.

Więcej informacji o typach wiadomości znajdziesz w artykule Powiadomienia i wiadomości z danymi.

Wywołanie zwrotne onMessageReceived ma krótki okres wykonania. Na długość tego okna może wpływać wiele czynników, w tym opóźnienia systemu operacyjnego, czas uruchamiania aplikacji, zablokowanie wątku głównego przez inne operacje lub zbyt długie wykonywanie poprzednich wywołań onMessageReceived.

Z tego powodu w onMessageReceived należy unikać długotrwałych zadań (takich jak pobieranie obrazów z serwera w celu wyświetlenia ich w powiadomieniu). Zamiast tego zaplanuj zadanie za pomocą WorkManager, aby obsługiwać wszystkie zadania, których wykonanie może zająć więcej niż kilka sekund. Więcej informacji o priorytecie wiadomości i jego wpływie na przetwarzanie znajdziesz w artykule Przetwarzanie wiadomości o wysokim i normalnym priorytecie.

Edytowanie pliku manifestu aplikacji

Aby korzystać z FirebaseMessagingService, musisz dodać do pliku manifestu aplikacji te elementy:

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

Zalecamy ustawienie wartości domyślnych, aby dostosować wygląd powiadomień. Możesz określić niestandardową domyślną ikonę i niestandardowy domyślny kolor, które będą stosowane, gdy w ładunku powiadomienia nie zostaną ustawione równoważne wartości.

Aby ustawić niestandardową ikonę domyślną i niestandardowy kolor, dodaj te wiersze w tagu 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 wyświetla i używa niestandardowej ikony domyślnej w przypadku:

  • Wszystkie wiadomości z powiadomieniami wysyłane z edytora powiadomień.
  • Każda wiadomość z powiadomieniem, która nie zawiera ikony w ładunku powiadomienia.

Jeśli niestandardowa ikona domyślna nie jest ustawiona, a ikona nie jest ustawiona 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 (ponad 100) dla Twojej aplikacji lub gdy urządzenie nie łączyło się z FCM od ponad miesiąca. W takich przypadkach możemy do Ciebie oddzwonić pod numer 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 wiadomości do aplikacji na tym urządzeniu, FCM nie zadzwoni na numer 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.

Obejmuje to wiadomości zawierające zarówno powiadomienie, jak i ładunek danych (oraz wszystkie wiadomości wysyłane z konsoli Powiadomienia). W takich przypadkach powiadomienie jest dostarczane do zasobnika systemowego urządzenia, a ładunek danych jest dostarczany w dodatkach intencji aktywności programu uruchamiającego.

Więcej informacji o dostarczaniu wiadomości do aplikacji znajdziesz w  FCM panelu raportowania, który rejestruje liczbę wysłanych i otwartych wiadomości na urządzeniach z Androidem i iOS, a także dane o „wyświetleniach” (powiadomieniach widocznych dla użytkowników) w przypadku aplikacji na Androida.