Aby kierować wiadomość na wiele urządzeń, skorzystaj z wiadomości tematycznych. Ta funkcja umożliwia wysyłanie wiadomości na wiele urządzeń, które wyraziły zgodę na dany temat.
Ten samouczek skupia się na wysyłaniu wiadomości tematycznych z serwera aplikacji za pomocą pakietu Admin SDK lub interfejsu API REST na potrzeby FCM, a także o odbieraniu i obsłudze tych wiadomości w aplikacji Apple. Na tej stronie znajdziesz listę wszystkich kroków, które pozwolą Ci to osiągnąć – od konfiguracji po weryfikację. Ta strona może więc zawierać czynności, które zostały już wykonane, jeśli skonfigurowałeś(-aś) aplikację kliencką Apple na potrzeby FCM lub masz za sobą kroki wysyłania pierwszej wiadomości.
Dodaj Firebase do projektu Apple
W tej sekcji znajdziesz zadania, które mogły zostać wykonane, jeśli masz już włączone inne funkcje Firebase w swojej aplikacji. W przypadku FCM musisz przesłać klucz uwierzytelniania APNs i zarejestrować się do otrzymywania zdalnych powiadomień.
Wymagania wstępne
Zainstaluj następujące elementy:
- Xcode 14.1 lub nowsza wersja
Sprawdź, czy Twój projekt spełnia te wymagania:
- Twój projekt musi być kierowany na te wersje platformy lub nowsze:
- iOS 11
- macOS 10.13
- tvOS 12
- watchOS 6
- Twój projekt musi być kierowany na te wersje platformy lub nowsze:
Skonfiguruj fizyczne urządzenie Apple do uruchamiania aplikacji i wykonaj te czynności:
- Uzyskaj klucz uwierzytelniania Apple Push Notification na swoim koncie dewelopera Apple.
- Włącz powiadomienia push w XCode w sekcji App > Capabilities (Aplikacja > Funkcje).
- Zaloguj się w Firebase, korzystając ze swojego konta Google.
Jeśli nie masz jeszcze projektu Xcode, a chcesz tylko wypróbować usługę Firebase, możesz pobrać krótkie wprowadzenie (przykłady).
Tworzenie projektu Firebase
Zanim dodasz Firebase do aplikacji Apple, musisz utworzyć projekt Firebase, który będzie połączony z tą aplikacją. Więcej informacji o projektach Firebase znajdziesz w artykule Omówienie projektów Firebase.
Zarejestruj aplikację w Firebase
Aby używać Firebase w swojej aplikacji Apple, musisz ją zarejestrować w projekcie Firebase. Rejestracja aplikacji często nazywa się „dodaniem” jej do projektu.
Otwórz konsolę Firebase.
Aby uruchomić przepływ pracy konfiguracji, na środku strony przeglądu projektu kliknij ikonę iOS+.
Jeśli masz już aplikację dodaną do projektu Firebase, kliknij Dodaj aplikację, aby wyświetlić opcje platformy.
W polu identyfikator pakietu wpisz identyfikator pakietu aplikacji.
(Opcjonalnie) Podaj inne informacje o aplikacji: Pseudonim aplikacji i Identyfikator sklepu z aplikacjami.
Kliknij Zarejestruj aplikację.
Dodaj plik konfiguracji Firebase
Kliknij Download GoogleService-Info.plist, aby uzyskać plik konfiguracyjny platform Firebase Apple (
GoogleService-Info.plist
).Przenieś plik konfiguracji do katalogu głównego projektu Xcode. Jeśli pojawi się taka prośba, wybierz opcję dodania pliku konfiguracyjnego do wszystkich środowisk docelowych.
Jeśli masz w projekcie wiele identyfikatorów pakietów, musisz powiązać każdy z nich z zarejestrowaną aplikacją w konsoli Firebase, tak aby każda aplikacja miała własny plik GoogleService-Info.plist
.
Dodaj pakiety SDK Firebase do swojej aplikacji
Użyj menedżera pakietów Swift, aby zainstalować zależności Firebase i nimi zarządzać.
- Po otwarciu projektu aplikacji przejdź w Xcode do File > Add Packages (Plik > Dodaj pakiety).
- Gdy pojawi się prośba, dodaj repozytorium SDK platform Apple Platform SDK Firebase:
- Wybierz bibliotekę Komunikacji w chmurze Firebase.
- Dodaj flagę
-ObjC
do sekcji Inne flagi łączące w ustawieniach kompilacji celu. - Aby zapewnić optymalną jakość korzystania z Komunikacji w chmurze Firebase (FCM), zalecamy włączenie Google Analytics w projekcie Firebase i dodanie do aplikacji pakietu SDK Firebase dla Google Analytics. Możesz wybrać bibliotekę bez zbierania danych IDFA lub z zbieraniem identyfikatorów IDFA.
- Po zakończeniu Xcode automatycznie rozpocznie rozpoznawanie i pobieranie zależności w tle.
https://github.com/firebase/firebase-ios-sdk.git
Prześlij klucz uwierzytelniania APNs
Prześlij swój klucz uwierzytelniania APNs do Firebase. Jeśli nie masz jeszcze klucza uwierzytelniania APNs, utwórz go w Apple Developer Member Center.
-
W projekcie w konsoli Firebase kliknij ikonę koła zębatego, wybierz Ustawienia projektu, a następnie kartę Komunikacja w chmurze.
-
W sekcji Klucz uwierzytelniania APNs w sekcji Konfiguracja aplikacji na iOS kliknij przycisk Prześlij.
-
Przejdź do lokalizacji, w której masz zapisany klucz, wybierz go i kliknij Otwórz. Dodaj identyfikator klucza (dostępny w Apple Developer Member Center) i kliknij Prześlij.
Zainicjuj Firebase w swojej aplikacji
Musisz dodać do swojej aplikacji kod inicjowania Firebase. Zaimportuj moduł Firebase i skonfiguruj udostępnioną instancję, jak pokazano poniżej:
- Zaimportuj moduł
FirebaseCore
do obiektuUIApplicationDelegate
, a także wszystkie inne moduły Firebase używane przez przedstawiciela aplikacji. Aby na przykład użyć Cloud Firestore i Uwierzytelniania:Certyfikat 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 współdzieloną instancję
FirebaseApp
w metodzieapplication(_:didFinishLaunchingWithOptions:)
przedstawiciela aplikacji:Certyfikat 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ć przedstawiciela aplikacji i dołączyć go do struktury
App
za pomocąUIApplicationDelegateAdaptor
lubNSApplicationDelegateAdaptor
. Musisz też wyłączyć przełączanie przekazywania dostępu do aplikacji. Więcej informacji znajdziesz w instrukcjach SwiftUI.Certyfikat SwiftUI
@main struct YourApp: App { // register app delegate for Firebase setup @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate var body: some Scene { WindowGroup { NavigationView { ContentView() } } } }
Zarejestruj się, aby otrzymywać powiadomienia zdalne
Przy uruchamianiu lub w wybranym momencie przepływu aplikacji zarejestruj ją na potrzeby powiadomień zdalnych. WywołajregisterForRemoteNotifications
, jak pokazano poniżej:
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 w aplikacji klienckiej
Aplikacje klienckie mogą subskrybować dowolny istniejący temat lub utworzyć nowy temat. Gdy aplikacja kliencka subskrybuje nową nazwę tematu (takiego, którego jeszcze nie ma w Twoim projekcie Firebase), w FCM tworzony jest nowy temat o tej nazwie, a każdy klient może go zasubskrybować.
Aby zasubskrybować temat, wywołaj metodę subskrypcji z głównego wątku aplikacji (FCM nie jest bezpieczne w wątkach). Jeśli początkowo prośba o subskrypcję się nie powiedzie, FCM automatycznie spróbuje ponownie. W sytuacjach, gdy subskrypcji nie można ukończyć, subskrypcja zgłasza błąd, który można wychwytywać przez moduł obsługi uzupełniania, 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 żądanie asynchroniczne do backendu FCM i subskrybuje klienta do danego tematu. Przed wywołaniem funkcji subscribeToTopic:topic
sprawdź, czy instancja aplikacji klienckiej otrzymała już token rejestracji przez wywołanie zwrotne didReceiveRegistrationToken
.
Przy każdym uruchomieniu aplikacji FCM sprawdza, czy wszystkie żądane tematy zostały subskrybowane. Aby anulować subskrypcję, wywołaj unsubscribeFromTopic:topic
, a funkcja FCM anuluje subskrypcję tematu w tle.
Odbieranie i obsługę wiadomości dotyczących tematów
FCM dostarcza wiadomości tematyczne tak samo jak inne wiadomości.
Wdróż application(_:didReceiveRemoteNotification:fetchCompletionHandler:)
w następujący sposób:
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 żądań wysyłania
Po utworzeniu tematu przez subskrybowanie instancji aplikacji klienckiej w temacie po stronie klienta lub za pomocą interfejsu API serwera możesz wysyłać wiadomości do tematu. Jeśli po raz pierwszy tworzysz żądania wysyłania żądań do FCM, przeczytaj przewodnik po środowisku serwera i FCM, w którym znajdziesz ważne informacje i informacje o konfiguracji.
W logice wysyłania w backendzie określ odpowiednią nazwę tematu, jak pokazano 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 określające tematy docelowe. Na przykład poniższy warunek spowoduje wysłanie wiadomości do urządzeń, które subskrybują TopicA
i TopicB
lub TopicC
:
"'TopicA' in topics && ('TopicB' in topics || 'TopicC' in topics)"
FCM najpierw ocenia warunki w nawiasach, a potem ocenia wyrażenie od lewej do prawej. W przypadku powyższego wyrażenia użytkownik zasubskrybowany
dowolny pojedynczy temat nie otrzymuje wiadomości. Podobnie użytkownik, który nie subskrybuje kanału TopicA
, nie otrzyma tej wiadomości. Wynika to z tych kombinacji:
TopicA
iTopicB
TopicA
iTopicC
Wyrażenie warunkowe może zawierać 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
- Za pomocą serwera możesz subskrybować instancje aplikacji klienckich w tematach i wykonywać inne zadania związane z zarządzaniem. Zobacz Zarządzanie subskrypcjami tematów na serwerze.