Nachrichten mit Firebase Cloud Messaging empfangen

In diesem Leitfaden wird beschrieben, wie Sie Firebase Cloud Messaging in Ihren mobilen und Webclient-Apps einrichten, damit Sie Nachrichten zuverlässig empfangen können.

Verwenden Sie einen Dienst, der FirebaseMessagingService erweitert, um Nachrichten zu empfangen. Ihr Dienst sollte die Callbacks onMessageReceived und onDeletedMessages überschreiben.

onMessageReceived ist für die meisten Nachrichtentypen verfügbar, mit den folgenden Ausnahmen:

  • Benachrichtigungen, die zugestellt werden, wenn Ihre App im Hintergrund ausgeführt wird: In diesem Fall wird die Benachrichtigung in der Taskleiste des Geräts angezeigt. Wenn ein Nutzer auf eine Benachrichtigung tippt, wird standardmäßig der App Launcher geöffnet.

  • Nachrichten mit Benachrichtigungs- und Daten-Payload, wenn sie im Hintergrund empfangen werden. In diesem Fall wird die Benachrichtigung in der Taskleiste des Geräts angezeigt und die Daten-Payload wird in den Extras des Intents Ihrer Launcher-Aktivität bereitgestellt.

Zusammenfassung:

App-Status Benachrichtigung Daten Beides
Vordergrund onMessageReceived onMessageReceived onMessageReceived
Hintergrund Taskleiste onMessageReceived Benachrichtigung: Taskleiste Daten: in Extras des Intents.

Weitere Informationen zu Nachrichtentypen finden Sie unter Benachrichtigungen und Datenmeldungen.

Für den onMessageReceived-Callback werden Zeitüberschreitungen festgelegt, die es Ihnen ermöglichen, eine Benachrichtigung zu posten. Die Timer sind jedoch nicht dafür vorgesehen, dass die App auf das Netzwerk zugreifen oder zusätzliche Aufgaben ausführen kann. Wenn Ihre App also komplexere Aufgaben ausführt, müssen Sie zusätzliche Maßnahmen ergreifen, damit die App ihre Aufgaben erledigen kann.

Wenn Sie davon ausgehen, dass Ihre App für die Verarbeitung einer Nachricht fast 10 Sekunden benötigt, sollten Sie einen WorkManager-Job planen oder die Anleitung zu WakeLocks unten befolgen. In einigen Fällen kann das Zeitfenster für die Verarbeitung einer Nachricht kürzer als 10 Sekunden sein. Das hängt von Verzögerungen ab, die vor dem Aufrufen von onMessageReceived auftreten, z. B. Verzögerungen des Betriebssystems, App-Startzeit, Blockierung des Hauptthreads durch andere Vorgänge oder vorherige onMessageReceived-Aufrufe, die zu lange dauern. Nach Ablauf dieses Zeitlimits kann es sein, dass Ihre App beendet oder Einschränkungen bei der Ausführung im Hintergrund unterliegt. Latenzen für Netzwerktransaktionen und App-Start können erheblich sein. Wenn Sie sich nicht sicher sind, planen Sie daher für die Nachrichtenverarbeitung eine lange Ausführungszeit ein, wenn asynchrone Abhängigkeiten wie Netzwerkzugriff oder intensive Datenladeanforderungen bestehen.

App-Manifest bearbeiten

Wenn Sie FirebaseMessagingService verwenden möchten, müssen Sie Folgendes in das App-Manifest einfügen:

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

Außerdem sollten Sie Standardwerte festlegen, um das Erscheinungsbild von Benachrichtigungen anzupassen. Sie können ein benutzerdefiniertes Standardsymbol und eine benutzerdefinierte Standardfarbe angeben, die angewendet werden, wenn in der Benachrichtigungs-Payload keine entsprechenden Werte festgelegt sind.

Fügen Sie diese Zeilen in das application-Tag ein, um das benutzerdefinierte Standardsymbol und die benutzerdefinierte Farbe festzulegen:

<!-- 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 zeigt das benutzerdefinierte Standardsymbol an und verwendet es für

  • Alle Benachrichtigungen, die über den Benachrichtigungs-Composer gesendet werden.
  • Alle Benachrichtigungen, bei denen das Symbol nicht explizit in der Benachrichtigungs-Payload festgelegt ist.

Wenn kein benutzerdefiniertes Standardsymbol festgelegt ist und kein Symbol in der Benachrichtigungsnutzlast festgelegt ist, zeigt Android das in Weiß gerenderte Anwendungssymbol an.

Überschreiben onMessageReceived

Durch Überschreiben der Methode FirebaseMessagingService.onMessageReceived können Sie Aktionen basierend auf dem empfangenen RemoteMessage-Objekt ausführen und die Nachrichtendaten abrufen:

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

Gerät während der Verarbeitung von FCM-Nachrichten aktiv halten

Wenn Ihre App das Gerät während der Verarbeitung einer FCM-Nachricht aktiv halten muss, muss sie in dieser Zeit ein WakeLock verwenden oder einen WorkManager-Job erstellen. WakeLocks eignen sich gut für kurze Verarbeitungsvorgänge, die die Standardzeitüberschreitungen von onMessageReceived überschreiten könnten. Für längere Workflows, z. B. das Senden mehrerer serieller RPCs an Ihre Server, ist die Verwendung eines WorkManager-Jobs besser geeignet als ein WakeLock. In diesem Abschnitt geht es darum, wie Sie WakeLocks verwenden. Ein WakeLock verhindert, dass das Gerät in den Ruhemodus wechselt, während Ihre App ausgeführt wird. Dies kann zu einem erhöhten Akkuverbrauch führen. Die Verwendung von WakeLocks sollte daher Fällen vorbehalten sein, in denen Ihre App während der Verarbeitung der Nachricht nicht pausiert werden sollte, z. B.:

  • Zeitkritische Benachrichtigungen an den Nutzer
  • Interaktionen mit etwas, das sich nicht auf dem Gerät befindet und nicht unterbrochen werden sollte, z. B. Netzwerkübertragungen oder die Kommunikation mit einem anderen Gerät wie einer gekoppelten Smartwatch.

Zuerst müssen Sie dafür sorgen, dass Ihre App die WakeLock-Berechtigung anfordert. Das FCM SDK enthält diese Berechtigung standardmäßig, sodass normalerweise nichts hinzugefügt werden muss.

<uses-permission android:name="android.permission.WAKE_LOCK" />

Ihre App muss dann zu Beginn des FirebaseMessagingService.onMessageReceived()-Callbacks einen WakeLock abrufen und ihn am Ende des Callbacks freigeben.

Benutzerdefiniertes FirebaseMessagingService der App:

@Override
public void onMessageReceived(final RemoteMessage message) {
  // If this is a message that is time sensitive or shouldn't be interrupted
  WakeLock wakeLock = getSystemService(PowerManager.class).newWakeLock(PARTIAL_WAKE_LOCK, "myApp:messageReceived");
  try {
    wakeLock.acquire(TIMEOUT_MS);
    // handle message
    ...
  finally {
    wakeLock.release();
  }
}

Überschreiben onDeletedMessages

In einigen Situationen wird mit FCM keine Nachricht gesendet. Dies tritt auf, wenn zum Zeitpunkt der Verbindung zu viele Nachrichten (> 100) für Ihre App auf einem bestimmten Gerät ausstehen oder wenn das Gerät seit mehr als einem Monat keine Verbindung zu FCM hergestellt hat. In diesen Fällen erhalten Sie möglicherweise einen Rückruf unter FirebaseMessagingService.onDeletedMessages(). Wenn die App-Instanz diesen Callback empfängt, sollte sie eine vollständige Synchronisierung mit Ihrem App-Server durchführen. Wenn Sie in den letzten vier Wochen keine Nachricht an die App auf diesem Gerät gesendet haben, ruft FCM onDeletedMessages() nicht an.

Benachrichtigungen in einer im Hintergrund ausgeführten App verarbeiten

Wenn sich Ihre App im Hintergrund befindet, leitet Android Benachrichtigungen an die Taskleiste weiter. Wenn ein Nutzer auf die Benachrichtigung tippt, wird standardmäßig der App Launcher geöffnet.

Dazu gehören Nachrichten, die sowohl eine Benachrichtigungs- als auch eine Datennutzlast enthalten, sowie alle Nachrichten, die über die Notifications Console gesendet werden. In diesen Fällen wird die Benachrichtigung in der Taskleiste des Geräts angezeigt und die Daten-Payload wird in den Extras des Intents Ihrer Launcher-Aktivität bereitgestellt.

Informationen zur Zustellung von Nachrichten an Ihre App finden Sie im FCM-Berichtsdashboard. Dort wird die Anzahl der auf Apple- und Android-Geräten gesendeten und geöffneten Nachrichten sowie die Anzahl der Impressionen (von Nutzern gesehene Benachrichtigungen) für Android-Apps erfasst.