| Plattform auswählen: | iOS+ Android Web Flutter Unity C++ |
Je nach Gerätestatus werden eingehende Nachrichten unterschiedlich verarbeitet. Um diese Szenarien zu verstehen und zu erfahren, wie du FCM in deine eigene Anwendung integrieren kannst, ist es wichtig, die verschiedenen Zustände zu kennen, in denen sich ein Gerät befinden kann:
| Status | Beschreibung |
|---|---|
| Vordergrund | Wenn die Anwendung geöffnet, sichtbar und in Verwendung ist. |
| Hintergrund | Wenn die Anwendung geöffnet, aber im Hintergrund (minimiert) ist. Das ist in der Regel der Fall, wenn der Nutzer die Startbildschirmtaste auf dem Gerät gedrückt, über den App-Schnellzugriff zu einer anderen App gewechselt oder die Anwendung in einem anderen Tab (Web) geöffnet hat. |
| Beendet | Wenn das Gerät gesperrt ist oder die App nicht ausgeführt wird. |
Damit die Anwendung Nachrichtennutzlasten über FCM empfangen kann, müssen einige Voraussetzungen erfüllt sein:
- Die Anwendung muss mindestens einmal geöffnet worden sein, damit eine Registrierung bei FCM möglich ist.
- Wenn der Nutzer unter iOS die App im App-Schnellzugriff wegwischt, muss er sie manuell wieder öffnen, damit Hintergrundnachrichten wieder funktionieren.
- Wenn der Nutzer unter Android das Beenden der App über die Geräteeinstellungen erzwingt, muss er sie manuell wieder öffnen, damit Nachrichten funktionieren.
- Im Web müssen Sie mit Ihrem Web-Push-Zertifikat ein Token (mit
getToken()) angefordert haben.
Berechtigung zum Empfangen von Nachrichten anfordern
Unter iOS, macOS, im Web und unter Android 13 (oder höher) müssen Sie zuerst die Erlaubnis des Nutzers einholen, bevor FCM-Nutzlasten auf dem Gerät empfangen werden können.
Das Paket firebase_messaging bietet eine API zum Anfordern von Berechtigungen mit der Methode requestPermission. Diese API akzeptiert eine Reihe von benannten Argumenten, die die Art der Berechtigungen definieren, die Sie anfordern möchten, z. B. ob Nachrichten mit Benachrichtigungsnutzlasten einen Ton auslösen oder Nachrichten mit Siri vorlesen können. Standardmäßig werden mit der Methode sinnvolle Standardberechtigungen angefordert. In der Referenz-API finden Sie eine vollständige Dokumentation dazu, wofür die einzelnen Berechtigungen verwendet werden.
Rufen Sie zuerst die Methode aus Ihrer Anwendung auf. Unter iOS 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}');
Anhand der Property authorizationStatus des Objekts NotificationSettings, das von der Anfrage zurückgegeben wird, lässt sich die 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 Properties von NotificationSettings geben zurück, 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 verstanden wurden, kann deine Anwendung mit der Verarbeitung der eingehenden FCM-Nutzlasten beginnen.
Nachrichtenverarbeitung
Je nach aktuellem Status Ihrer Anwendung erfordern eingehende Nutzlasten verschiedener Nachrichtentypen unterschiedliche Implementierungen, um sie zu verarbeiten:
Vordergrundnachrichten
Wenn Sie Nachrichten verarbeiten möchten, während Ihre Anwendung im Vordergrund ausgeführt wird, überwachen 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 ein RemoteMessage mit verschiedenen Informationen zur Nutzlast, z. B. woher sie stammt, die eindeutige ID, die Sendezeit, ob sie eine Benachrichtigung enthielt und mehr. 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
Benachrichtigungen, die eingehen, während die App im Vordergrund ausgeführt wird, werden standardmäßig weder auf Android- noch auf iOS-Geräten angezeigt. Es ist jedoch möglich, dieses Verhalten zu überschreiben:
- 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 unterscheidet sich auf Android-, Apple- und webbasierten Plattformen.
Apple-Plattformen und Android
Registrieren Sie einen onBackgroundMessage-Handler, um Hintergrundnachrichten zu verarbeiten. Wenn Nachrichten empfangen werden, wird ein Isolat erzeugt (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 Folgendes in Bezug auf den Handler für Hintergrundnachrichten:
- Es darf keine anonyme Funktion sein.
- Es muss sich um eine Funktion der obersten Ebene handeln (z.B. keine Klassenmethode, die eine Initialisierung erfordert).
- Wenn Sie Flutter Version 3.3.0 oder höher verwenden, muss der Message Handler direkt über der Funktionsdeklaration mit
@pragma('vm:entry-point')annotiert werden. Andernfalls wird er möglicherweise während des Tree-Shakings für den Releasemodus 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 Logik auszuführen, die sich auf die Benutzeroberfläche auswirkt. Sie können jedoch Logik wie HTTP-Anfragen ausführen, E/A-Vorgänge ausführen (z.B. lokalen Speicher aktualisieren), mit anderen Plug-ins kommunizieren usw.
Außerdem wird empfohlen, die Logik so schnell wie möglich fertigzustellen. Das Ausführen langer, intensiver Aufgaben beeinträchtigt die Geräteleistung und kann dazu führen, dass das Betriebssystem den Prozess beendet. Wenn Aufgaben länger als 30 Sekunden dauern, kann das Gerät den Prozess automatisch beenden.
Web
Im Web schreiben Sie einen JavaScript-Service Worker, der im Hintergrund ausgeführt wird. Verwenden Sie den Service Worker, um Hintergrundnachrichten zu verarbeiten.
Erstellen Sie zuerst 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 das App- als auch das Messaging-SDK importiert, Firebase initialisiert und die Variable messaging bereitgestellt werden.
Als Nächstes muss der Worker registriert werden. Registrieren Sie den Worker in der Datei index.html, indem Sie das Tag <script> ändern, das Flutter bootstrapt:
<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 <script>-Tag, das Flutter bootstrapt, so ändern:
<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 die Flutter-Anwendung neu. Der Worker wird registriert und alle Hintergrundnachrichten werden mit dieser Datei verarbeitet.
Interaktion verarbeiten
Da Benachrichtigungen ein sichtbarer Hinweis sind, interagieren Nutzer häufig mit ihnen (durch Drücken). Das Standardverhalten sowohl unter Android als auch unter iOS ist das Öffnen der App. Wenn die Anwendung beendet wurde, wird sie gestartet. Wenn sie im Hintergrund ausgeführt wird, wird sie in den Vordergrund gebracht.
Je nach Inhalt einer Benachrichtigung kann es sinnvoll sein, die Interaktion des Nutzers beim Öffnen der Anwendung zu verarbeiten. Wenn beispielsweise eine neue Chatnachricht über eine Benachrichtigung gesendet wird und der Nutzer darauf tippt, soll die entsprechende Unterhaltung geöffnet werden, 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 Zustand geöffnet wird, wird einFuturemit einemRemoteMessagezurückgegeben. Nach dem Verbrauch wird dasRemoteMessageentfernt.onMessageOpenedApp: EinStream, der eineRemoteMessagepostet, wenn die Anwendung aus einem Hintergrundstatus geöffnet wird.
Wir empfehlen, beide Szenarien zu berücksichtigen, um eine reibungslose UX für Ihre Nutzer zu gewährleisten. Das folgende Codebeispiel zeigt, 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 mit Interaktionen umgehen, hängt von der Einrichtung Ihrer Anwendung ab. Das vorherige Beispiel zeigt eine einfache Abbildung mit einem StatefulWidget.
Nachrichten lokalisieren
Sie haben zwei Möglichkeiten, lokalisierte Strings zu senden:
- Speichern Sie die bevorzugte Sprache jedes Nutzers auf Ihrem Server und senden Sie benutzerdefinierte Benachrichtigungen für jede Sprache.
- Bette lokalisierte Strings in deine App ein und nutze die integrierten Spracheinstellungen des Betriebssystems.
So verwenden Sie die zweite Methode:
Android
Geben Sie die Nachrichten in der Standardsprache in
resources/values/strings.xmlan:<string name="notification_title">Hello world</string> <string name="notification_message">This is a message</string>Geben Sie die übersetzten Nachrichten im Verzeichnis
values-languagean. Geben Sie beispielsweise französische Nachrichten inresources/values-fr/strings.xmlan:<string name="notification_title">Bonjour le monde</string> <string name="notification_message">C'est un message</string>Verwende in der Servernutzlast anstelle der Schlüssel
title,messageundbodydie Schlüsseltitle_loc_keyundbody_loc_keyfür deine lokalisierte Nachricht und setze sie auf das Attributnameder Nachricht, die du anzeigen möchtest.Die Nachrichtennutzlast sieht so aus:
{ "android": { "notification": { "title_loc_key": "notification_title", "body_loc_key": "notification_message" } } }
iOS
Geben Sie Ihre Nachrichten in der Standardsprache in
Base.lproj/Localizable.stringsan:"NOTIFICATION_TITLE" = "Hello World"; "NOTIFICATION_MESSAGE" = "This is a message";Geben Sie die übersetzten Nachrichten im Verzeichnis
language.lprojan. Geben Sie beispielsweise französische Nachrichten infr.lproj/Localizable.stringsan:"NOTIFICATION_TITLE" = "Bonjour le monde"; "NOTIFICATION_MESSAGE" = "C'est un message";Die Nachrichtennutzlast sieht so aus:
{ "apns": { "payload": { "alert": { "title-loc-key": "NOTIFICATION_TITLE", "loc-key": "NOTIFICATION_MESSAGE" } } } }
Export von Nachrichtenzustelldaten aktivieren
Sie können Ihre Nachrichtendaten zur weiteren Analyse nach BigQuery exportieren. Mit BigQuery können Sie die Daten mit BigQuery SQL analysieren, zu einem anderen Cloud-Anbieter exportieren oder 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 Notifications Composer gesendet wird.
Wenn Sie den Export aktivieren möchten, folgen Sie zuerst der Anleitung im Dokument BigQuery-Datenexport. Wenn Sie die Funktion programmatisch auf App-Instanzebene aktivieren, können Sie Endnutzer um Erlaubnis 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 durch den folgenden Inhalt ersetzen.
#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 v9-Version muss gebündelt werden. Sie müssen also einen Bundler wie esbuild verwenden, damit der Service Worker funktioniert. In der Beispiel-App sehen Sie, wie Sie dies erreichen.
Nach der Migration zum v9 SDK 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 auf iOS-Geräten anzeigen
Damit auf Apple-Geräten in eingehenden FCM Notifications Bilder aus der FCM-Nutzlast angezeigt werden, müssen Sie eine zusätzliche Benachrichtigungsdienst-Erweiterung hinzufügen und Ihre App so konfigurieren, dass sie diese verwendet.
Wenn Sie die Firebase-Telefonauthentifizierung verwenden, müssen Sie das Firebase Auth-Pod zu Ihrem Podfile hinzufügen.
Schritt 1: Notification Service Extension hinzufügen
- Klicken Sie in Xcode auf File > New > Target… (Datei > Neu > Ziel…).
- In einem modalen Fenster wird eine Liste möglicher Ziele angezeigt. Scrollen Sie zu Notification Service Extension oder verwenden Sie den Filter, um diese Option auszuwählen. Klicken Sie auf Weiter.
- Fügen Sie einen Produktnamen hinzu (verwenden Sie „ImageNotification“, um dieser Anleitung zu folgen), wählen Sie entweder
SwiftoderObjective-Caus und klicken Sie auf Fertigstellen. - Klicken Sie auf Aktivieren, um das Schema zu aktivieren.
Schritt 2: Ziel zum Podfile hinzufügen
Swift
Sorgen Sie dafür, dass Ihre neue Erweiterung Zugriff auf das Swift-Paket FirebaseMessaging hat, indem Sie es Ihrem Runner-Ziel hinzufügen:
Fügen Sie das Firebase Apple Platforms SDK über den Navigator hinzu: File > Add Package Dependencies…
Suchen Sie nach der Paket-URL oder geben Sie sie ein:
none https://github.com/firebase/firebase-ios-sdkZu Projekt
Runnerhinzufügen: Paket hinzufügenWählen Sie „FirebaseMessaging“ aus und fügen Sie es dem Ziel „ImageNotification“ hinzu: 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:
Öffnen Sie im Navigator das Podfile: Pods > Podfile.
Gehen 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' endInstallieren oder aktualisieren Sie Ihre Pods mit
pod installaus dem Verzeichnisiosodermacos.
Schritt 3: Erweiterungsassistenten verwenden
An diesem Punkt sollte alles noch normal funktionieren. Im letzten Schritt wird der Erweiterungs-Helper aufgerufen.
Swift
Wählen Sie im Navigator die Erweiterung „ImageNotification“ aus.
Öffnen Sie die Datei
NotificationService.swift.Ersetzen Sie den Inhalt von
NotificationService.swiftdurch: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
Wählen Sie im Navigator die Erweiterung „ImageNotification“ aus.
Öffnen Sie die Datei
NotificationService.m.Importieren Sie oben in der Datei
FirebaseMessaging.hdirekt nachNotificationService.h.Ersetzen Sie den Inhalt von
NotificationService.mdurch:#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 die Nutzlast Ihrer Benachrichtigung einfügen. Weitere Informationen finden Sie unter Sendeanfrage erstellen.