Nachrichten in Flutter-Apps empfangen

Plattform auswählen : iOS+ Android Web Flutter Unity C++


Je nach Gerätestatus werden eingehende Nachrichten unterschiedlich verarbeitet. Um diese Szenarien zu verstehen und FCM in Ihre eigene Anwendung zu integrieren, ist es wichtig, die verschiedenen Status zu kennen, in denen sich ein Gerät befinden kann:

Status Beschreibung
Vordergrund Die Anwendung ist geöffnet, sichtbar und wird verwendet.
Hintergrund Die Anwendung ist geöffnet, aber im Hintergrund (minimiert). Dies geschieht in der Regel, wenn der Nutzer die Startbildschirmtaste auf dem Gerät gedrückt hat, mit der App-Umschaltfunktion zu einer anderen App gewechselt ist oder die Anwendung in einem anderen Tab geöffnet hat (Web).
Beendet Das Gerät ist gesperrt oder die Anwendung wird nicht ausgeführt.

Es gibt einige Voraussetzungen, die erfüllt sein müssen, bevor die Anwendung Nachrichten-Nutzlasten mit FCM empfangen kann:

  • Die Anwendung muss mindestens einmal geöffnet worden sein (um die Registrierung bei FCM zu ermöglichen).
  • Wenn der Nutzer die Anwendung auf iOS-Geräten über die App-Umschaltfunktion schließt, muss sie manuell wieder geöffnet werden, damit Hintergrundnachrichten wieder funktionieren.
  • Wenn der Nutzer die App auf Android-Geräten über die Geräteeinstellungen beendet, muss sie manuell wieder geöffnet werden, damit Nachrichten wieder funktionieren.
  • Im Web müssen Sie mit Ihrem Web-Push-Zertifikat ein Token angefordert haben (getToken()).

Berechtigung zum Empfangen von Nachrichten anfordern

Auf iOS-, macOS-, Web- und Android 13-Geräten (oder neuer) müssen Sie zuerst die Berechtigung des Nutzers einholen, bevor FCM-Nutzlasten auf Ihrem Gerät empfangen werden können.

Das Paket firebase_messaging bietet eine API zum Anfordern von Berechtigungen mit der requestPermission Methode. Diese API akzeptiert eine Reihe benannter Argumente, die den Typ der Berechtigungen definieren, die Sie anfordern möchten. Sie können beispielsweise festlegen, ob Nachrichten mit Benachrichtigungs-Nutzlasten einen Ton auslösen oder Nachrichten mit Siri vorgelesen werden können. Standardmäßig fordert die Methode sinnvolle Standardberechtigungen an. Die Referenz-API enthält eine vollständige Dokumentation dazu, wofür die einzelnen Berechtigungen verwendet werden.

Rufen Sie die Methode in Ihrer Anwendung auf, um zu beginnen (auf iOS-Geräten wird ein integriertes modales Fenster angezeigt, im Web wird der API-Ablauf des Browsers ausgelöst):

FirebaseMessaging messaging = FirebaseMessaging.instance;

NotificationSettings settings = await messaging.requestPermission(
  alert: true,
  announcement: false,
  badge: true,
  carPlay: false,
  criticalAlert: false,
  provisional: false,
  sound: true,
);

print('User granted permission: ${settings.authorizationStatus}');

Mit der Eigenschaft authorizationStatus des Objekts NotificationSettings, das von der Anfrage zurückgegeben wird, können Sie die allgemeine Entscheidung des Nutzers ermitteln:

  • authorized: Der Nutzer hat die Berechtigung erteilt.
  • denied: Der Nutzer hat die Berechtigung verweigert.
  • notDetermined: Der Nutzer hat noch nicht entschieden, ob er die Berechtigung erteilen möchte.
  • provisional: Der Nutzer hat eine vorläufige Berechtigung erteilt.

Die anderen Eigenschaften von NotificationSettings geben an, ob eine bestimmte Berechtigung auf dem aktuellen Gerät aktiviert, deaktiviert oder nicht unterstützt wird.

Sobald die Berechtigung erteilt wurde und die verschiedenen Arten von Gerätestatus bekannt sind, kann Ihre Anwendung die eingehenden FCM-Nutzlasten verarbeiten.

Nachrichtenverarbeitung

Je nach aktuellem Status Ihrer Anwendung erfordern eingehende Nutzlasten verschiedener Nachrichtentypen unterschiedliche Implementierungen für die Verarbeitung:

Vordergrundnachrichten

Wenn Sie Nachrichten verarbeiten möchten, während sich Ihre Anwendung im Vordergrund befindet, beobachten Sie den Stream onMessage.

FirebaseMessaging.onMessage.listen((RemoteMessage message) {
  print('Got a message whilst in the foreground!');
  print('Message data: ${message.data}');

  if (message.notification != null) {
    print('Message also contained a notification: ${message.notification}');
  }
});

Der Stream enthält eine RemoteMessage mit verschiedenen Informationen zur Nutzlast, z. B. zur Quelle, zur eindeutigen ID, zum Sendezeitpunkt und dazu, ob sie eine Benachrichtigung enthält. Da die Nachricht abgerufen wurde, während sich Ihre Anwendung im Vordergrund befindet, können Sie direkt auf den Status und Kontext Ihrer Flutter-Anwendung zugreifen.

Vordergrund- und Benachrichtigungsnachrichten

Benachrichtigungsnachrichten, die eingehen, während sich die Anwendung im Vordergrund befindet, zeigen standardmäßig keine sichtbare Benachrichtigung an, sowohl unter Android als auch unter iOS. Dieses Verhalten kann jedoch überschrieben werden:

  • Unter Android müssen Sie einen Benachrichtigungskanal mit hoher Priorität erstellen.
  • Unter iOS können Sie die Präsentationsoptionen für die Anwendung aktualisieren.

Hintergrundnachrichten

Die Verarbeitung von Hintergrundnachrichten ist auf Android-, Apple- und webbasierten Plattformen unterschiedlich.

Apple-Plattformen und Android

Registrieren Sie einen onBackgroundMessage-Handler, um Hintergrundnachrichten zu verarbeiten. Wenn Nachrichten empfangen werden, wird ein Isolat erstellt (nur Android, iOS/macOS erfordert kein separates Isolat), sodass Sie Nachrichten auch dann verarbeiten können, wenn Ihre Anwendung nicht ausgeführt wird.

Beachten Sie beim Handler für Hintergrundnachrichten Folgendes:

  1. Er darf keine anonyme Funktion sein.
  2. Er muss eine Funktion der obersten Ebene sein (z.B. keine Klassenmethode, die initialisiert werden muss).
  3. Wenn Sie Flutter Version 3.3.0 oder höher verwenden, muss der Nachrichten-Handler mit @pragma('vm:entry-point') direkt über der Funktions deklaration annotiert werden. Andernfalls wird er im Release modus möglicherweise durch Tree Shaking entfernt.
@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  // If you're going to use other Firebase services in the background, such as Firestore,
  // make sure you call `initializeApp` before using other Firebase services.
  await Firebase.initializeApp();

  print("Handling a background message: ${message.messageId}");
}

void main() {
  FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
  runApp(MyApp());
}

Da der Handler in einem eigenen Isolat außerhalb des Anwendungskontexts ausgeführt wird, ist es nicht möglich, den Anwendungsstatus zu aktualisieren oder UI-beeinträchtigende Logik auszuführen. Sie können jedoch Logik wie HTTP-Anfragen ausführen, E/A-Vorgänge ausführen (z.B. lokalen Speicher aktualisieren) und mit anderen Plug-ins kommunizieren.

Außerdem sollten Sie Ihre Logik so schnell wie möglich abschließen. Lange, intensive Aufgaben beeinträchtigen die Geräteleistung und können dazu führen, dass das Betriebssystem den Prozess beendet. Wenn Aufgaben länger als 30 Sekunden ausgeführt werden, beendet das Gerät den Prozess möglicherweise automatisch.

Web

Schreiben Sie im Web einen JavaScript Service Worker der im Hintergrund ausgeführt wird. Verwenden Sie den Service Worker, um Hintergrundnachrichten zu verarbeiten.

Erstellen Sie dazu eine neue Datei im Verzeichnis web und nennen Sie sie firebase-messaging-sw.js:

// See this file for the latest firebase-js-sdk version:
// https://github.com/firebase/flutterfire/blob/main/packages/firebase_core/firebase_core_web/lib/src/firebase_sdk_version.dart
importScripts("https://www.gstatic.com/firebasejs/10.7.0/firebase-app-compat.js");
importScripts("https://www.gstatic.com/firebasejs/10.7.0/firebase-messaging-compat.js");

firebase.initializeApp({
  apiKey: "...",
  authDomain: "...",
  databaseURL: "...",
  projectId: "...",
  storageBucket: "...",
  messagingSenderId: "...",
  appId: "...",
});

const messaging = firebase.messaging();

// Optional:
messaging.onBackgroundMessage((message) => {
  console.log("onBackgroundMessage", message);
});

In der Datei müssen sowohl die App- als auch die Messaging-SDKs importiert, Firebase initialisiert und die Variable messaging verfügbar gemacht werden.

Als Nächstes muss der Worker registriert werden. Registrieren Sie den Worker in der Datei index.html, indem Sie das Tag <script> ändern, mit dem Flutter gestartet wird:

<script src="flutter_bootstrap.js" async>
  if ('serviceWorker' in navigator) {
    window.addEventListener('load', function () {
      navigator.serviceWorker.register('firebase-messaging-sw.js', {
        scope: '/firebase-cloud-messaging-push-scope',
      });
    });
  }
</script>

Wenn Sie noch das alte Vorlagensystem verwenden, können Sie den Worker registrieren, indem Sie das Tag <script> ändern, mit dem Flutter wie folgt gestartet wird:

<html>
<body>
  <script>
      var serviceWorkerVersion = null;
      var scriptLoaded = false;
      function loadMainDartJs() {
        if (scriptLoaded) {
          return;
        }
        scriptLoaded = true;
        var scriptTag = document.createElement('script');
        scriptTag.src = 'main.dart.js';
        scriptTag.type = 'application/javascript';
        document.body.append(scriptTag);
      }

      if ('serviceWorker' in navigator) {
        // Service workers are supported. Use them.
        window.addEventListener('load', function () {
          // Register Firebase Messaging service worker.
          navigator.serviceWorker.register('firebase-messaging-sw.js', {
            scope: '/firebase-cloud-messaging-push-scope',
          });

          // Wait for registration to finish before dropping the <script> tag.
          // Otherwise, the browser will load the script multiple times,
          // potentially different versions.
          var serviceWorkerUrl =
            'flutter_service_worker.js?v=' + serviceWorkerVersion;

          navigator.serviceWorker.register(serviceWorkerUrl).then((reg) => {
            function waitForActivation(serviceWorker) {
              serviceWorker.addEventListener('statechange', () => {
                if (serviceWorker.state == 'activated') {
                  console.log('Installed new service worker.');
                  loadMainDartJs();
                }
              });
            }
            if (!reg.active && (reg.installing || reg.waiting)) {
              // No active web worker and we have installed or are installing
              // one for the first time. Simply wait for it to activate.
              waitForActivation(reg.installing ?? reg.waiting);
            } else if (!reg.active.scriptURL.endsWith(serviceWorkerVersion)) {
              // When the app updates the serviceWorkerVersion changes, so we
              // need to ask the service worker to update.
              console.log('New service worker available.');
              reg.update();
              waitForActivation(reg.installing);
            } else {
              // Existing service worker is still good.
              console.log('Loading app from service worker.');
              loadMainDartJs();
            }
          });

          // If service worker doesn't succeed in a reasonable amount of time,
          // fallback to plaint <script> tag.
          setTimeout(() => {
            if (!scriptLoaded) {
              console.warn(
                'Failed to load app from service worker. Falling back to plain <script> tag.'
              );
              loadMainDartJs();
            }
          }, 4000);
        });
      } else {
        // Service workers not supported. Just drop the <script> tag.
        loadMainDartJs();
      }
  </script>
</body>

Starten Sie als Nächstes Ihre Flutter-Anwendung neu. Der Worker wird registriert und alle Hintergrundnachrichten werden mit dieser Datei verarbeitet.

Interaktion verarbeiten

Da Benachrichtigungen sichtbar sind, interagieren Nutzer häufig damit (indem sie darauf tippen). Standardmäßig wird sowohl unter Android als auch unter iOS die Anwendung geöffnet. Wenn die Anwendung beendet ist, wird sie gestartet. Wenn sie im Hintergrund ausgeführt wird, wird sie in den Vordergrund gebracht.

Je nach Inhalt einer Benachrichtigung möchten Sie möglicherweise die Nutzerinteraktion verarbeiten, wenn die Anwendung geöffnet wird. Wenn beispielsweise eine neue Chatnachricht über eine Benachrichtigung gesendet wird und der Nutzer darauf tippt, möchten Sie möglicherweise die entsprechende Unterhaltung öffnen, wenn die Anwendung geöffnet wird.

Das Paket firebase-messaging bietet zwei Möglichkeiten, diese Interaktion zu verarbeiten:

  • getInitialMessage(): Wenn die Anwendung aus einem beendeten Status geöffnet wird, wird ein Future mit einer RemoteMessage zurückgegeben. Nach der Verwendung wird die RemoteMessage entfernt.
  • onMessageOpenedApp: Ein Stream, der eine RemoteMessage postet, wenn die Anwendung aus einem Hintergrundstatus geöffnet wird.

Es empfiehlt sich, beide Szenarien zu verarbeiten, um eine reibungslose Nutzererfahrung zu gewährleisten. Im folgenden Codebeispiel wird gezeigt, wie das geht:

class Application extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _Application();
}

class _Application extends State<Application> {
  // It is assumed that all messages contain a data field with the key 'type'
  Future<void> setupInteractedMessage() async {
    // Get any messages which caused the application to open from
    // a terminated state.
    RemoteMessage? initialMessage =
        await FirebaseMessaging.instance.getInitialMessage();

    // If the message also contains a data property with a "type" of "chat",
    // navigate to a chat screen
    if (initialMessage != null) {
      _handleMessage(initialMessage);
    }

    // Also handle any interaction when the app is in the background using a
    // Stream listener
    FirebaseMessaging.onMessageOpenedApp.listen(_handleMessage);
  }

  void _handleMessage(RemoteMessage message) {
    if (message.data['type'] == 'chat') {
      Navigator.pushNamed(context, '/chat',
        arguments: ChatArguments(message),
      );
    }
  }

  @override
  void initState() {
    super.initState();

    // Run code required to handle interacted messages in an async function
    // as initState() must not be async
    setupInteractedMessage();
  }

  @override
  Widget build(BuildContext context) {
    return Text("...");
  }
}

Wie Sie die Interaktion verarbeiten, hängt von der Einrichtung Ihrer Anwendung ab. Das vorherige Beispiel zeigt eine grundlegende Darstellung mit einem StatefulWidget.

Nachrichten lokalisieren

Sie können lokalisierte Strings auf zwei verschiedene Arten senden:

  • Speichern Sie die bevorzugte Sprache jedes Nutzers auf Ihrem Server und senden Sie für jede Sprache benutzerdefinierte Benachrichtigungen.
  • Betten Sie lokalisierte Strings in Ihre App ein und nutzen Sie die integrierten Gebietsschemaeinstellungen des Betriebssystems.

So verwenden Sie die zweite Methode:

Android

  1. Geben Sie Ihre Standardnachrichten in resources/values/strings.xml an:

    <string name="notification_title">Hello world</string>
    <string name="notification_message">This is a message</string>
    
  2. Geben Sie die übersetzten Nachrichten im Verzeichnis values-language an. Geben Sie beispielsweise französische Nachrichten in resources/values-fr/strings.xml an:

    <string name="notification_title">Bonjour le monde</string>
    <string name="notification_message">C'est un message</string>
    
  3. Verwenden Sie in der Servernutzlast anstelle der Schlüssel title, message und body die Schlüssel title_loc_key und body_loc_key für Ihre lokalisierte Nachricht, und legen Sie sie auf das Attribut name der Nachricht fest, die Sie anzeigen möchten.

    Die Nachrichten-Nutzlast sieht so aus:

    {
      "android": {
         "notification": {
           "title_loc_key": "notification_title",
           "body_loc_key": "notification_message"
         }
      }
    }
    

iOS

  1. Geben Sie Ihre Standardnachrichten in Base.lproj/Localizable.strings an:

    "NOTIFICATION_TITLE" = "Hello World";
    "NOTIFICATION_MESSAGE" = "This is a message";
    
  2. Geben Sie die übersetzten Nachrichten im language.lproj Verzeichnis an. Geben Sie beispielsweise französische Nachrichten in fr.lproj/Localizable.strings an:

    "NOTIFICATION_TITLE" = "Bonjour le monde";
    "NOTIFICATION_MESSAGE" = "C'est un message";
    

    Die Nachrichten-Nutzlast sieht so aus:

    {
      "apns": {
         "payload": {
           "alert": {
             "title-loc-key": "NOTIFICATION_TITLE",
             "loc-key": "NOTIFICATION_MESSAGE"
           }
         }
      }
    }
    

Export von Daten zur Nachrichtenzustellung aktivieren

Sie können Ihre Nachrichtendaten zur weiteren Analyse nach BigQuery exportieren. Mit BigQuery können Sie die Daten mit BigQuery SQL analysieren, sie zu einem anderen Cloud-Anbieter exportieren oder die Daten für Ihre benutzerdefinierten ML-Modelle verwenden. Ein Export nach BigQuery umfasst alle verfügbaren Daten für Nachrichten, unabhängig vom Nachrichtentyp oder davon, ob die Nachricht über die API oder den Benachrichtigungs-Composer gesendet wird.

Folgen Sie zuerst der Anleitung unter Daten nach BigQuery exportieren, um den Export zu aktivieren. Wenn Sie den Export programmatisch auf App-Instanzebene aktivieren, können Sie Endnutzer um die Berechtigung bitten, ihre Daten zur Nachrichtenzustellung zu analysieren (empfohlen). Folgen Sie dieser Anleitung, um den Export programmatisch zu aktivieren:

Android

Sie können den folgenden Code verwenden:

await FirebaseMessaging.instance.setDeliveryMetricsExportToBigQuery(true);

iOS

Für iOS müssen Sie AppDelegate.m mit dem folgenden Inhalt ändern.

#import "AppDelegate.h"
#import "GeneratedPluginRegistrant.h"
#import <Firebase/Firebase.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  [GeneratedPluginRegistrant registerWithRegistry:self];
  // Override point for customization after application launch.
  return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

- (void)application:(UIApplication *)application
    didReceiveRemoteNotification:(NSDictionary *)userInfo
          fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
  [[FIRMessaging extensionHelper] exportDeliveryMetricsToBigQueryWithMessageInfo:userInfo];
}

@end

Web

Für das Web müssen Sie Ihren Service Worker ändern, um die Version 9 des SDK zu verwenden. Die Version 9 muss gebündelt werden. Sie müssen also einen Bundler wie esbuild verwenden, damit der Service Worker funktioniert. In der Beispiel App erfahren Sie, wie Sie das erreichen.

Nachdem Sie zu Version 9 des SDK migriert sind, können Sie den folgenden Code verwenden:

import {
  experimentalSetDeliveryMetricsExportedToBigQueryEnabled,
  getMessaging,
} from 'firebase/messaging/sw';
...

const messaging = getMessaging(app);
experimentalSetDeliveryMetricsExportedToBigQueryEnabled(messaging, true);

Vergessen Sie nicht, yarn build auszuführen, um die neue Version Ihres Service Workers in den Ordner web zu exportieren.

Bilder in Benachrichtigungen unter iOS anzeigen

Auf Apple-Geräten müssen Sie eine zusätzliche Benachrichtigungsdienst-Erweiterung hinzufügen und Ihre App so konfigurieren, dass sie diese verwendet, damit in eingehenden FCM-Benachrichtigungen Bilder aus der FCM-Nutzlast angezeigt werden.

Wenn Sie die Firebase-Telefonauthentifizierung verwenden, müssen Sie den Firebase Auth-Pod zu Ihrer Podfile hinzufügen.

Schritt 1: Benachrichtigungsdienst-Erweiterung hinzufügen

  1. Klicken Sie in Xcode auf File > New > Target... (Datei > Neu > Ziel).
  2. In einem modalen Fenster wird eine Liste möglicher Ziele angezeigt. Scrollen Sie zu Notification Service Extension (Benachrichtigungsdienst-Erweiterung) oder verwenden Sie den Filter, um diese Option auszuwählen. Klicken Sie auf Next (Weiter).
  3. Fügen Sie einen Produktnamen hinzu (verwenden Sie „ImageNotification“, um dieser Anleitung zu folgen), wählen Sie entweder Swift oder Objective-C aus und klicken Sie auf Finish (Fertigstellen).
  4. Aktivieren Sie das Schema, indem Sie auf Activate (Aktivieren) klicken.

Schritt 2: Ziel zur Podfile hinzufügen

Swift

Achten Sie darauf, dass Ihre neue Erweiterung Zugriff auf das Swift-Paket FirebaseMessaging hat, indem Sie es Ihrem Ziel Runner hinzufügen:

  1. Fügen Sie im Navigator das Firebase Apple Platforms SDK hinzu: File > Add Package Dependencies...

  2. Suchen Sie nach der Paket-URL oder geben Sie sie ein: none https://github.com/firebase/firebase-ios-sdk

  3. Fügen Sie das Paket dem Projekt Runner hinzu: Add Package (Paket hinzufügen).

  4. Wählen Sie „FirebaseMessaging“ aus und fügen Sie es dem Ziel „ImageNotification“ hinzu: Add Package (Paket hinzufügen).

Objective-C

Achten Sie darauf, dass Ihre neue Erweiterung Zugriff auf den Pod Firebase/Messaging hat, indem Sie ihn in der Podfile hinzufügen:

  1. Öffnen Sie im Navigator die Podfile: Pods > Podfile.

  2. Scrollen Sie zum Ende der Datei und fügen Sie Folgendes hinzu:

    target 'ImageNotification' do
      use_frameworks!
      pod 'Firebase/Auth' # Add this line if you are using FirebaseAuth phone authentication
      pod 'Firebase/Messaging'
    end
    
  3. Installieren oder aktualisieren Sie Ihre Pods mit pod install aus dem Verzeichnis ios oder macos.

Schritt 3: Erweiterungs-Helper verwenden

An diesem Punkt sollte alles normal funktionieren. Im letzten Schritt wird der Erweiterungs-Helper aufgerufen.

Swift

  1. Wählen Sie im Navigator die Erweiterung „ImageNotification“ aus.

  2. Öffnen Sie die Datei NotificationService.swift.

  3. Ersetzen Sie den Inhalt von NotificationService.swift durch:

    import UserNotifications
    import FirebaseMessaging
    
    class NotificationService: UNNotificationServiceExtension {
    
        var contentHandler: ((UNNotificationContent) -> Void)?
        var bestAttemptContent: UNMutableNotificationContent?
    
        override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
            self.contentHandler = contentHandler
            bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
    
            Messaging.serviceExtension().populateNotificationContent(bestAttemptContent!, withContentHandler: contentHandler)
        }
    
        override func serviceExtensionTimeWillExpire() {
            if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {
                contentHandler(bestAttemptContent)
            }
        }
    }
    

Objective-C

  1. Wählen Sie im Navigator die Erweiterung „ImageNotification“ aus.

  2. Öffnen Sie die Datei NotificationService.m.

  3. Importieren Sie oben in der Datei FirebaseMessaging.h direkt nach NotificationService.h.

    Ersetzen Sie den Inhalt von NotificationService.m durch:

    #import "NotificationService.h"
    #import "FirebaseMessaging.h"
    #import <FirebaseAuth/FirebaseAuth-Swift.h> // Add this line if you are using FirebaseAuth phone authentication
    #import <UIKit/UIKit.h> // Add this line if you are using FirebaseAuth phone authentication
    
    @interface NotificationService () <NSURLSessionDelegate>
    
    @property(nonatomic) void (^contentHandler)(UNNotificationContent *contentToDeliver);
    @property(nonatomic) UNMutableNotificationContent *bestAttemptContent;
    
    @end
    
    @implementation NotificationService
    
    /* Uncomment this if you are using Firebase Auth
    - (BOOL)application:(UIApplication *)app
                openURL:(NSURL *)url
                options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options {
      if ([[FIRAuth auth] canHandleURL:url]) {
        return YES;
      }
      return NO;
    }
    
    - (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts {
      for (UIOpenURLContext *urlContext in URLContexts) {
        [FIRAuth.auth canHandleURL:urlContext.URL];
      }
    }
    */
    
    - (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
        self.contentHandler = contentHandler;
        self.bestAttemptContent = [request.content mutableCopy];
    
        // Modify the notification content here...
        [[FIRMessaging extensionHelper] populateNotificationContent:self.bestAttemptContent withContentHandler:contentHandler];
    }
    
    - (void)serviceExtensionTimeWillExpire {
        // Called just before the extension will be terminated by the system.
        // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
        self.contentHandler(self.bestAttemptContent);
    }
    
    @end
    

Schritt 4: Bild zur Nutzlast hinzufügen

Sie können jetzt ein Bild in Ihre Benachrichtigungs-Nutzlast einfügen. Weitere Informationen finden Sie unter Sendeanfrage erstellen.