Nachrichten an mehrere Geräte auf Apple-Plattformen senden

Wenn Sie eine Nachricht an mehrere Geräte senden möchten, verwenden Sie Themen-Messaging. Mit dieser Funktion können Sie eine Nachricht an mehrere Geräte senden, die ein bestimmtes Thema aktiviert haben.

In dieser Anleitung geht es hauptsächlich darum, wie Sie Nachrichten zu Themen über Ihren App-Server mit der Admin SDK oder der REST API für FCM senden und in einer Apple-App empfangen und verarbeiten. Auf dieser Seite sind alle Schritte von der Einrichtung bis zur Bestätigung aufgeführt. Möglicherweise werden also Schritte beschrieben, die Sie bereits ausgeführt haben, wenn Sie eine Apple-Client-App für FCM eingerichtet oder die Schritte zum Senden Ihrer ersten Nachricht ausgeführt haben.

Firebase zu meinem Apple-Projekt hinzufügen

In diesem Abschnitt werden Aufgaben beschrieben, die Sie möglicherweise abgeschlossen haben, wenn Sie bereits andere Firebase-Funktionen für Ihre App aktiviert haben. Insbesondere für FCM müssen Sie Ihren APNs-Authentifizierungsschlüssel hochladen und sich für Remote-Benachrichtigungen registrieren.

Vorbereitung

  • Installieren Sie Folgendes:

    • Xcode 15.2 oder höher
  • Ihr Projekt muss die folgenden Anforderungen erfüllen:

    • Ihr Projekt muss auf die folgenden Plattformversionen oder höher ausgerichtet sein:
      • iOS 13
      • macOS 10.15
      • tvOS 13
      • watchOS 7
  • Richten Sie ein physisches Apple-Gerät ein, um Ihre App auszuführen, und führen Sie die folgenden Aufgaben aus:

    • Holen Sie sich einen Apple Push Notification-Authentifizierungsschlüssel für Ihr Apple-Entwicklerkonto.
    • Aktivieren Sie Push-Benachrichtigungen in XCode unter App > Funktionen.

Wenn Sie noch kein Xcode-Projekt haben und nur ein Firebase-Produkt ausprobieren möchten, können Sie eines unserer Schnellstartbeispiele herunterladen.

Firebase-Projekt erstellen

Bevor Sie Firebase zu Ihrer Apple-App hinzufügen können, müssen Sie ein Firebase-Projekt erstellen, um eine Verbindung zu Ihrer App herzustellen. Weitere Informationen zu Firebase-Projekten finden Sie unter Firebase-Projekte.

App bei Firebase registrieren

Damit Sie Firebase in Ihrer Apple-App verwenden können, müssen Sie Ihre App bei Ihrem Firebase-Projekt registrieren. Die Registrierung Ihrer App wird oft als „Hinzufügen“ der App zu Ihrem Projekt bezeichnet.

  1. Rufen Sie die Firebase-Konsole auf.

  2. Klicken Sie in der Mitte der Projektübersichtsseite auf das iOS+-Symbol, um den Einrichtungsworkflow zu starten.

    Wenn Sie Ihrem Firebase-Projekt bereits eine App hinzugefügt haben, klicken Sie auf App hinzufügen, um die Plattformoptionen aufzurufen.

  3. Geben Sie die Bundle-ID Ihrer App in das Feld Bundle-ID ein.

  4. Optional: Geben Sie weitere App-Informationen ein: App-Alias und App Store-ID.

  5. Klicken Sie auf App registrieren.

Firebase-Konfigurationsdatei hinzufügen

  1. Klicken Sie auf GoogleService-Info.plist herunterladen, um die Konfigurationsdatei für Firebase-Apple-Plattformen (GoogleService-Info.plist) abzurufen.

  2. Verschieben Sie Ihre Konfigurationsdatei in das Stammverzeichnis Ihres Xcode-Projekts. Wählen Sie bei Aufforderung aus, dass die Konfigurationsdatei allen Zielen hinzugefügt werden soll.

Wenn Sie in Ihrem Projekt mehrere Bundle-IDs haben, müssen Sie jede Bundle-ID in der Firebase-Konsole einer registrierten Anwendung zuordnen, damit jede Anwendung eine eigene GoogleService-Info.plist-Datei haben kann.

Firebase SDKs zu Ihrer App hinzufügen

Verwenden Sie Swift Package Manager, um Firebase-Abhängigkeiten zu installieren und zu verwalten.

  1. Öffnen Sie Ihr App-Projekt und gehen Sie in Xcode zu File > Add Packages (Datei > Pakete hinzufügen).
  2. Fügen Sie bei entsprechender Aufforderung das Firebase Apple Platforms SDK-Repository hinzu:
  3.   https://github.com/firebase/firebase-ios-sdk.git
  4. Wählen Sie die Bibliothek Firebase Cloud Messaging aus.
  5. Fügen Sie das Flag -ObjC im Abschnitt Other Linker Flags (Weitere Verknüpfungsmerker) der Build-Einstellungen des Ziels hinzu.
  6. Für eine optimale Nutzung von Firebase Cloud Messaging empfehlen wir, Google Analytics in Ihrem Firebase-Projekt zu aktivieren und Ihrer App das Firebase SDK für Google Analytics hinzuzufügen. Sie können entweder die Bibliothek ohne oder mit IDFA-Erfassung auswählen.
  7. Wenn Sie fertig, beginnt Xcode automatisch, Ihre Abhängigkeiten im Hintergrund aufzulösen und herunterzuladen.

APNs-Authentifizierungsschlüssel hochladen

Laden Sie Ihren APNs-Authentifizierungsschlüssel in Firebase hoch. Wenn Sie noch keinen APN-Authentifizierungsschlüssel haben, erstellen Sie einen im Apple Developer Member Center.

  1. Klicken Sie in der Firebase Console in Ihrem Projekt auf das Zahnradsymbol, dann auf Projekteinstellungen und dann auf den Tab Cloud Messaging.

  2. Klicken Sie unter APNs-Authentifizierungsschlüssel im Abschnitt Konfiguration der iOS-App auf die Schaltfläche Hochladen.

  3. Rufen Sie den Speicherort auf, an dem Sie den Schlüssel gespeichert haben, wählen Sie ihn aus und klicken Sie auf Öffnen. Fügen Sie die Schlüssel-ID für den Schlüssel hinzu (verfügbar im Apple Developer Member Center) und klicken Sie auf Hochladen.

Firebase in Ihrer App initialisieren

Sie müssen Ihrer Anwendung Firebase-Initialisierungscode hinzufügen. Importieren Sie das Firebase-Modul und konfigurieren Sie eine freigegebene Instanz wie hier gezeigt:

  1. Importieren Sie das Modul FirebaseCore in Ihre UIApplicationDelegate sowie alle anderen Firebase-Module, die der App-Delegate verwendet. So verwenden Sie beispielsweise Cloud Firestore und Authentication:

    SwiftUI

    import SwiftUI
    import FirebaseCore
    import FirebaseFirestore
    import FirebaseAuth
    // ...
          

    Swift

    import FirebaseCore
    import FirebaseFirestore
    import FirebaseAuth
    // ...
          

    Objective-C

    @import FirebaseCore;
    @import FirebaseFirestore;
    @import FirebaseAuth;
    // ...
          
  2. Konfigurieren Sie in der Methode application(_:didFinishLaunchingWithOptions:) des Anwendungsdelegats eine freigegebene Instanz FirebaseApp:

    SwiftUI

    // Use Firebase library to configure APIs
    FirebaseApp.configure()

    Swift

    // Use Firebase library to configure APIs
    FirebaseApp.configure()

    Objective-C

    // Use Firebase library to configure APIs
    [FIRApp configure];
  3. Wenn Sie SwiftUI verwenden, müssen Sie einen Anwendungsdelegierten erstellen und über UIApplicationDelegateAdaptor oder NSApplicationDelegateAdaptor an das App-Objekt anhängen. Außerdem müssen Sie App Delegate Swizzling deaktivieren. Weitere Informationen finden Sie in der SwiftUI-Anleitung.

    SwiftUI

    @main
    struct YourApp: App {
      // register app delegate for Firebase setup
      @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
    
      var body: some Scene {
        WindowGroup {
          NavigationView {
            ContentView()
          }
        }
      }
    }
          

Für Remote-Benachrichtigungen registrieren

Registrieren Sie Ihre App entweder beim Start oder an der gewünschten Stelle im Ablauf Ihrer Anwendung für Remote-Benachrichtigungen. Rufen Sie registerForRemoteNotifications wie hier gezeigt auf:

Swift

UNUserNotificationCenter.current().delegate = self

let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
  options: authOptions,
  completionHandler: { _, _ in }
)

application.registerForRemoteNotifications()

Objective-C

[UNUserNotificationCenter currentNotificationCenter].delegate = self;
UNAuthorizationOptions authOptions = UNAuthorizationOptionAlert |
    UNAuthorizationOptionSound | UNAuthorizationOptionBadge;
[[UNUserNotificationCenter currentNotificationCenter]
    requestAuthorizationWithOptions:authOptions
    completionHandler:^(BOOL granted, NSError * _Nullable error) {
      // ...
    }];

[application registerForRemoteNotifications];

Clientanwendung für ein Thema abonnieren

Client-Apps können jedes vorhandene Thema abonnieren oder ein neues Thema erstellen. Wenn eine Client-App einen neuen Themennamen abonniert, der für Ihr Firebase-Projekt noch nicht vorhanden ist, wird in FCM ein neues Thema mit diesem Namen erstellt. Dieses kann dann von allen Clients abonniert werden.

Wenn Sie ein Thema abonnieren möchten, rufen Sie die Abomethode aus dem Hauptthread Ihrer Anwendung auf. FCM ist nicht threadsicher. Wenn die Aboanfrage anfänglich fehlschlägt, wird sie von FCM automatisch wiederholt. Wenn das Abo nicht abgeschlossen werden kann, löst es einen Fehler aus, den du in einem Abschluss-Handler wie unten gezeigt abfangen kannst:

Swift

Messaging.messaging().subscribe(toTopic: "weather") { error in
  print("Subscribed to weather topic")
}

Objective-C

[[FIRMessaging messaging] subscribeToTopic:@"weather"
                                completion:^(NSError * _Nullable error) {
  NSLog(@"Subscribed to weather topic");
}];

Dieser Aufruf sendet eine asynchrone Anfrage an das FCM-Backend und abonniert den Client für das angegebene Thema. Bevor du subscribeToTopic:topic aufrufst, muss die Client-App-Instanz bereits ein Registrierungstoken über den Callback didReceiveRegistrationToken erhalten haben.

Bei jedem Start der App prüft FCM, ob alle angeforderten Themen abonniert wurden. Wenn Sie das Abo kündigen möchten, rufen Sie unsubscribeFromTopic:topic auf. FCM kündigt das Abo des Themas im Hintergrund.

Nachrichten zu Themen empfangen und bearbeiten

FCM liefert Themennachrichten auf die gleiche Weise wie andere Downstream-Nachrichten.

Implementieren Sie application(_:didReceiveRemoteNotification:fetchCompletionHandler:) wie unten gezeigt:

Swift

func application(_ application: UIApplication,
                 didReceiveRemoteNotification userInfo: [AnyHashable: Any]) async
  -> UIBackgroundFetchResult {
  // If you are receiving a notification message while your app is in the background,
  // this callback will not be fired till the user taps on the notification launching the application.
  // TODO: Handle data of notification

  // With swizzling disabled you must let Messaging know about the message, for Analytics
  // Messaging.messaging().appDidReceiveMessage(userInfo)

  // Print message ID.
  if let messageID = userInfo[gcmMessageIDKey] {
    print("Message ID: \(messageID)")
  }

  // Print full message.
  print(userInfo)

  return UIBackgroundFetchResult.newData
}

Objective-C

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
    fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
  // If you are receiving a notification message while your app is in the background,
  // this callback will not be fired till the user taps on the notification launching the application.
  // TODO: Handle data of notification

  // With swizzling disabled you must let Messaging know about the message, for Analytics
  // [[FIRMessaging messaging] appDidReceiveMessage:userInfo];

  // ...

  // Print full message.
  NSLog(@"%@", userInfo);

  completionHandler(UIBackgroundFetchResultNewData);
}

Sendeanfragen erstellen

Nachdem Sie ein Thema erstellt haben, indem Sie Client-App-Instanzen entweder clientseitig für das Thema abonniert oder die Server API verwendet haben, können Sie Nachrichten an das Thema senden. Wenn Sie zum ersten Mal Sendeanfragen für FCM erstellen, finden Sie im Leitfaden zu Ihrer Serverumgebung und FCM wichtige Hintergrundinformationen und Einrichtungsanleitungen.

Geben Sie in der Sendelogik im Back-End den gewünschten Themennamen wie gezeigt an:

Node.js

// The topic name can be optionally prefixed with "/topics/".
const topic = 'highScores';

const message = {
  data: {
    score: '850',
    time: '2:45'
  },
  topic: topic
};

// Send a message to devices subscribed to the provided topic.
getMessaging().send(message)
  .then((response) => {
    // Response is a message ID string.
    console.log('Successfully sent message:', response);
  })
  .catch((error) => {
    console.log('Error sending message:', error);
  });

Java

// The topic name can be optionally prefixed with "/topics/".
String topic = "highScores";

// See documentation on defining a message payload.
Message message = Message.builder()
    .putData("score", "850")
    .putData("time", "2:45")
    .setTopic(topic)
    .build();

// Send a message to the devices subscribed to the provided topic.
String response = FirebaseMessaging.getInstance().send(message);
// Response is a message ID string.
System.out.println("Successfully sent message: " + response);

Python

# The topic name can be optionally prefixed with "/topics/".
topic = 'highScores'

# See documentation on defining a message payload.
message = messaging.Message(
    data={
        'score': '850',
        'time': '2:45',
    },
    topic=topic,
)

# Send a message to the devices subscribed to the provided topic.
response = messaging.send(message)
# Response is a message ID string.
print('Successfully sent message:', response)

Go

// The topic name can be optionally prefixed with "/topics/".
topic := "highScores"

// See documentation on defining a message payload.
message := &messaging.Message{
	Data: map[string]string{
		"score": "850",
		"time":  "2:45",
	},
	Topic: topic,
}

// Send a message to the devices subscribed to the provided topic.
response, err := client.Send(ctx, message)
if err != nil {
	log.Fatalln(err)
}
// Response is a message ID string.
fmt.Println("Successfully sent message:", response)

C#

// The topic name can be optionally prefixed with "/topics/".
var topic = "highScores";

// See documentation on defining a message payload.
var message = new Message()
{
    Data = new Dictionary<string, string>()
    {
        { "score", "850" },
        { "time", "2:45" },
    },
    Topic = topic,
};

// Send a message to the devices subscribed to the provided topic.
string response = await FirebaseMessaging.DefaultInstance.SendAsync(message);
// Response is a message ID string.
Console.WriteLine("Successfully sent message: " + response);

REST

POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1

Content-Type: application/json
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA
{
  "message":{
    "topic" : "foo-bar",
    "notification" : {
      "body" : "This is a Firebase Cloud Messaging Topic Message!",
      "title" : "FCM Message"
      }
   }
}

cURL-Befehl:

curl -X POST -H "Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA" -H "Content-Type: application/json" -d '{
  "message": {
    "topic" : "foo-bar",
    "notification": {
      "body": "This is a Firebase Cloud Messaging Topic Message!",
      "title": "FCM Message"
    }
  }
}' https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1

Wenn Sie eine Nachricht an eine Kombination von Themen senden möchten, geben Sie eine Bedingung an. Das ist ein boolescher Ausdruck, der die Zielthemen angibt. Mit der folgenden Bedingung werden beispielsweise Nachrichten an Geräte gesendet, die TopicA und entweder TopicB oder TopicC abonniert haben:

"'TopicA' in topics && ('TopicB' in topics || 'TopicC' in topics)"

Bei FCM werden zuerst alle Bedingungen in Klammern und dann der Ausdruck von links nach rechts ausgewertet. In der obigen Ausdrucksform erhält ein Nutzer, der ein einzelnes Thema abonniert hat, die Nachricht nicht. Ein Nutzer, der TopicA nicht abonniert hat, erhält die Nachricht ebenfalls nicht. In folgenden Fällen erhalten Sie sie:

  • TopicA und TopicB
  • TopicA und TopicC

Sie können bis zu fünf Themen in den bedingten Ausdruck aufnehmen.

So senden Sie eine Anfrage an eine Bedingung:

Node.js

// Define a condition which will send to devices which are subscribed
// to either the Google stock or the tech industry topics.
const condition = '\'stock-GOOG\' in topics || \'industry-tech\' in topics';

// See documentation on defining a message payload.
const message = {
  notification: {
    title: '$FooCorp up 1.43% on the day',
    body: '$FooCorp gained 11.80 points to close at 835.67, up 1.43% on the day.'
  },
  condition: condition
};

// Send a message to devices subscribed to the combination of topics
// specified by the provided condition.
getMessaging().send(message)
  .then((response) => {
    // Response is a message ID string.
    console.log('Successfully sent message:', response);
  })
  .catch((error) => {
    console.log('Error sending message:', error);
  });

Java

// Define a condition which will send to devices which are subscribed
// to either the Google stock or the tech industry topics.
String condition = "'stock-GOOG' in topics || 'industry-tech' in topics";

// See documentation on defining a message payload.
Message message = Message.builder()
    .setNotification(Notification.builder()
        .setTitle("$GOOG up 1.43% on the day")
        .setBody("$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.")
        .build())
    .setCondition(condition)
    .build();

// Send a message to devices subscribed to the combination of topics
// specified by the provided condition.
String response = FirebaseMessaging.getInstance().send(message);
// Response is a message ID string.
System.out.println("Successfully sent message: " + response);

Python

# Define a condition which will send to devices which are subscribed
# to either the Google stock or the tech industry topics.
condition = "'stock-GOOG' in topics || 'industry-tech' in topics"

# See documentation on defining a message payload.
message = messaging.Message(
    notification=messaging.Notification(
        title='$GOOG up 1.43% on the day',
        body='$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.',
    ),
    condition=condition,
)

# Send a message to devices subscribed to the combination of topics
# specified by the provided condition.
response = messaging.send(message)
# Response is a message ID string.
print('Successfully sent message:', response)

Go

// Define a condition which will send to devices which are subscribed
// to either the Google stock or the tech industry topics.
condition := "'stock-GOOG' in topics || 'industry-tech' in topics"

// See documentation on defining a message payload.
message := &messaging.Message{
	Data: map[string]string{
		"score": "850",
		"time":  "2:45",
	},
	Condition: condition,
}

// Send a message to devices subscribed to the combination of topics
// specified by the provided condition.
response, err := client.Send(ctx, message)
if err != nil {
	log.Fatalln(err)
}
// Response is a message ID string.
fmt.Println("Successfully sent message:", response)

C#

// Define a condition which will send to devices which are subscribed
// to either the Google stock or the tech industry topics.
var condition = "'stock-GOOG' in topics || 'industry-tech' in topics";

// See documentation on defining a message payload.
var message = new Message()
{
    Notification = new Notification()
    {
        Title = "$GOOG up 1.43% on the day",
        Body = "$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.",
    },
    Condition = condition,
};

// Send a message to devices subscribed to the combination of topics
// specified by the provided condition.
string response = await FirebaseMessaging.DefaultInstance.SendAsync(message);
// Response is a message ID string.
Console.WriteLine("Successfully sent message: " + response);

REST

POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1

Content-Type: application/json
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA
{
   "message":{
    "condition": "'dogs' in topics || 'cats' in topics",
    "notification" : {
      "body" : "This is a Firebase Cloud Messaging Topic Message!",
      "title" : "FCM Message",
    }
  }
}

cURL-Befehl:

curl -X POST -H "Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA" -H "Content-Type: application/json" -d '{
  "notification": {
    "title": "FCM Message",
    "body": "This is a Firebase Cloud Messaging Topic Message!",
  },
  "condition": "'dogs' in topics || 'cats' in topics"
}' https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1

Nächste Schritte

  • Sie können Ihren Server verwenden, um für Clientanwendungsinstanzen Themen zu abonnieren und andere Verwaltungsaufgaben auszuführen. Weitere Informationen finden Sie unter Themenabos auf dem Server verwalten.