Aby kierować wiadomości na wiele urządzeń, użyj wiadomości tematycznych. Ta funkcja umożliwia wysyłanie wiadomości na wiele urządzeń, które subskrybują określony temat.
Ten samouczek skupia się na wysyłaniu wiadomości do tematów z serwera aplikacji za pomocą Admin SDK lub interfejsu REST API dla FCM oraz na odbieraniu i obsłudze tych wiadomości w aplikacji na iOS. Na tej stronie znajdziesz wszystkie kroki, które należy wykonać, aby to osiągnąć – od konfiguracji po weryfikację. Jeśli masz już skonfigurowaną aplikację kliencką na iOS dla FCM lub wykonane kroki wysyłania pierwszej wiadomości, niektóre z nich mogą być już za Tobą.
Dodawanie Firebase do projektu Apple
W tej sekcji opisujemy zadania, które mogłeś(-aś) już wykonać, jeśli masz włączone inne funkcje Firebase w swojej aplikacji. W przypadku FCM musisz przesłać klucz uwierzytelniania APNs i zarejestrować się w celu otrzymywania powiadomień zdalnych.
Wymagania wstępne
Zainstaluj te elementy:
- Xcode 16.2 lub nowsze
Upewnij się, że Twój projekt spełnia te wymagania:
- Twój projekt musi być przeznaczony na te wersje platformy lub nowsze:
- iOS 13
- macOS 10.15
- tvOS 13
- watchOS 7
- Twój projekt musi być przeznaczony na te wersje platformy lub nowsze:
Skonfiguruj fizyczne urządzenie Apple, na którym będzie działać Twoja aplikacja, i wykonaj te czynności:
- Uzyskaj klucz uwierzytelniania usługi Apple Push Notification na koncie dewelopera Apple.
- Włącz powiadomienia push w XCode w sekcji App > Capabilities (Aplikacja > Funkcje).
- Zaloguj się w Firebase przy użyciu konta Google.
Jeśli nie masz jeszcze projektu Xcode i chcesz tylko wypróbować usługę Firebase, możesz pobrać jeden z naszych przykładowych projektów.
Tworzenie projektu Firebase
Zanim dodasz Firebase do aplikacji na urządzenia Apple, musisz utworzyć projekt Firebase, aby połączyć go z aplikacją. Więcej informacji o projektach Firebase znajdziesz w artykule Informacje o projektach Firebase.
Rejestrowanie aplikacji w Firebase
Aby korzystać z Firebase w aplikacji na urządzenia Apple, musisz zarejestrować ją w projekcie Firebase. Rejestracja aplikacji jest często nazywana „dodawaniem” aplikacji do projektu.
Otwórz Firebasekonsolę.
W centrum strony „Opis” projektu kliknij ikonę iOS+, aby uruchomić proces konfiguracji.
Jeśli masz już aplikację w projekcie Firebase, kliknij Dodaj aplikację, aby wyświetlić opcje platformy.
W polu bundle ID wpisz identyfikator pakietu aplikacji.
(Opcjonalnie) wpisz inne informacje o aplikacji: pseudonim aplikacji i identyfikator App Store.
Kliknij Zarejestruj aplikację.
Dodawanie pliku konfiguracyjnego Firebase
Kliknij Pobierz GoogleService-Info.plist, aby uzyskać plik konfiguracyjny Firebase aplikacji (
GoogleService-Info.plist
).Przenieś plik konfiguracyjny do katalogu głównego projektu Xcode. Jeśli pojawi się odpowiedni komunikat, wybierz opcję dodania pliku konfiguracyjnego do wszystkich miejsc docelowych.
Jeśli w projekcie masz kilka identyfikatorów pakietu, musisz powiązać każdy z nich z zarejestrowaną aplikacją w konsoli Firebase, aby każda aplikacja miała własny plik GoogleService-Info.plist
.
Dodawanie pakietów SDK Firebase do aplikacji
Do instalacji zależności Firebase i do zarządzania nimi możesz używać menedżera pakietów Swift.
- Po otwarciu projektu aplikacji wybierz w Xcode opcję File > Add Packages (Plik > Dodaj pakiety).
- Gdy pojawi się prośba, dodaj repozytorium pakietu SDK Firebase na platformy Apple:
- Wybierz bibliotekę Firebase Cloud Messaging.
- Dodaj flagę
-ObjC
do sekcji Other Linker Flags (Inne flagi linkera) w ustawieniach kompilacji projektu. - Aby w pełni korzystać z Firebase Cloud Messaging, zalecamy włączenie Google Analytics w projekcie Firebase i dodanie do aplikacji pakietu SDK Firebase dla Google Analytics. Możesz wybrać bibliotekę bez zbierania identyfikatora IDFA lub z jego zbieraniem. Zapoznaj się z naszymi odpowiedziami na najczęstsze pytania dotyczące najnowszej organizacji modułów w Google Analytics dla pakietu SDK Firebase.
- Gdy skończysz, Xcode zacznie automatycznie wyszukiwać i pobierać zależności w tle.
https://github.com/firebase/firebase-ios-sdk.git
Prześlij klucz uwierzytelniania APNs
Prześlij klucz uwierzytelniania APNs do Firebase. Jeśli nie masz jeszcze klucza uwierzytelniania APNs, utwórz go w Centrum dla deweloperów Apple.
-
W projekcie w Firebase konsoli kliknij ikonę koła zębatego, wybierz Ustawienia projektu, a następnie kliknij kartę Cloud Messaging.
-
W sekcji Klucz uwierzytelniania APNs w obszarze Konfiguracja aplikacji na iOS kliknij przycisk Prześlij.
-
Przejdź do lokalizacji, w której został zapisany klucz, wybierz go i kliknij Otwórz. Dodaj identyfikator klucza (dostępny w Apple Developer Member Center) i kliknij Prześlij.
Inicjowanie Firebase w aplikacji
Musisz dodać do aplikacji kod inicjalizacji Firebase. Zaimportuj moduł Firebase i skonfiguruj udostępnioną instancję w sposób pokazany poniżej:
- Zaimportuj moduł
FirebaseCore
w plikuUIApplicationDelegate
, a także inne moduły Firebase, których używa delegat aplikacji. Aby na przykład użyć właściwości Cloud Firestore i 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; // ...
- Skonfiguruj udostępnioną instancję
FirebaseApp
w metodzieapplication(_:didFinishLaunchingWithOptions:)
delegata aplikacji: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];
- Jeśli używasz SwiftUI, musisz utworzyć delegata aplikacji i dołączyć go do struktury
App
za pomocąUIApplicationDelegateAdaptor
lubNSApplicationDelegateAdaptor
. Musisz też wyłączyć zamianę delegata aplikacji. Więcej informacji znajdziesz w instrukcjach dotyczących SwiftUI.SwiftUI
@main struct YourApp: App { // register app delegate for Firebase setup @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate var body: some Scene { WindowGroup { NavigationView { ContentView() } } } }
Rejestrowanie powiadomień zdalnych
Zarejestruj aplikację do otrzymywania powiadomień zdalnych podczas uruchamiania lub w odpowiednim momencie w jej działaniu. WywołajregisterForRemoteNotifications
w ten sposób:
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];
Subskrybowanie tematu przez aplikację kliencką
Aplikacje klienckie mogą subskrybować dowolny istniejący temat lub tworzyć nowy. Gdy aplikacja kliencka subskrybuje nową nazwę tematu (która nie istnieje jeszcze w Twoim projekcie Firebase), w FCM tworzony jest nowy temat o tej nazwie i każdy klient może go później subskrybować.
Aby zasubskrybować temat, wywołaj metodę subskrypcji z głównego wątku aplikacji (FCM nie jest bezpieczna dla wątków). Jeśli początkowo nie uda się wysłać prośby o subskrypcję, FCM automatycznie ponowi próbę. W przypadku, gdy subskrypcji nie można zrealizować, zgłasza ona błąd, który możesz przechwycić w procedurze obsługi zakończenia, jak pokazano poniżej:
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"); }];
To wywołanie wysyła asynchroniczne żądanie do FCMbackendu i subskrybuje klienta w danym temacie. Przed wywołaniem funkcji subscribeToTopic:topic
upewnij się, że instancja aplikacji klienckiej otrzymała już token rejestracyjny za pomocą wywołania zwrotnego didReceiveRegistrationToken
.
Za każdym razem, gdy aplikacja się uruchamia, FCM sprawdza, czy wszystkie żądane tematy zostały zasubskrybowane. Aby anulować subskrypcję, zadzwoń pod numer unsubscribeFromTopic:topic
, a FCM anuluje subskrypcję tematu w tle.
Odbieranie i obsługa wiadomości dotyczących tematu
FCM dostarcza wiadomości o tematach w taki sam sposób jak inne wiadomości wysyłane do urządzenia.
Wdróż application(_:didReceiveRemoteNotification:fetchCompletionHandler:)
w sposób pokazany poniżej:
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); }
Tworzenie próśb o wysłanie
Po utworzeniu tematu (przez subskrybowanie instancji aplikacji klienckiej w temacie po stronie klienta lub za pomocą interfejsu API serwera) możesz wysyłać do niego wiadomości. Jeśli po raz pierwszy tworzysz żądania wysyłania dla FCM, zapoznaj się z przewodnikiem dotyczącym środowiska serwera i FCM, aby uzyskać ważne informacje o konfiguracji i kontekście.
W logice wysyłania na backendzie określ nazwę tematu w sposób pokazany poniżej:
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"
}
}
}
Polecenie cURL:
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
Aby wysłać wiadomość do kombinacji tematów, określ warunek, czyli wyrażenie logiczne, które określa docelowe tematy. Na przykład ten warunek spowoduje wysłanie wiadomości na urządzenia, które subskrybują TopicA
oraz TopicB
lub TopicC
:
"'TopicA' in topics && ('TopicB' in topics || 'TopicC' in topics)"
FCM najpierw sprawdza warunki w nawiasach, a potem wyrażenie od lewej do prawej. W powyższym wyrażeniu użytkownik subskrybujący dowolny pojedynczy temat nie otrzyma wiadomości. Podobnie użytkownik, który nie subskrybuje TopicA
, nie otrzyma wiadomości. Te kombinacje otrzymują go:
TopicA
iTopicB
TopicA
iTopicC
W wyrażeniu warunkowym możesz uwzględnić maksymalnie 5 tematów.
Aby wysłać do warunku:
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",
}
}
}
Polecenie cURL:
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
Dalsze kroki
- Możesz używać serwera do subskrybowania instancji aplikacji klienckich w tematach i wykonywania innych zadań związanych z zarządzaniem. Zobacz Zarządzanie subskrypcjami tematów na serwerze.