Để nhắm đến nhiều thiết bị bằng một thông báo, hãy sử dụng tính năng Nhắn tin theo chủ đề. Tính năng này cho phép bạn gửi một thông báo đến nhiều thiết bị đã chọn nhận thông báo về một chủ đề cụ thể.
Hướng dẫn này tập trung vào việc gửi thông báo theo chủ đề từ máy chủ ứng dụng bằng cách sử dụng Admin SDK hoặc REST API cho FCM, cũng như nhận và xử lý các thông báo đó trong một ứng dụng Apple. Trang này liệt kê tất cả các bước để đạt được mục tiêu này, từ bước thiết lập đến bước xác minh. Vì vậy, có thể trang này sẽ đề cập đến những bước mà bạn đã hoàn tất nếu bạn đã thiết lập một ứng dụng khách Apple cho FCM hoặc đã thực hiện các bước để Gửi thông báo đầu tiên.
Thêm Firebase vào dự án Apple
Phần này đề cập đến những việc bạn có thể đã hoàn thành nếu đã bật các tính năng khác của Firebase cho ứng dụng. Cụ thể đối với FCM, bạn cần tải khoá xác thực APNs lên và đăng ký nhận thông báo từ xa.
Điều kiện tiên quyết
Cài đặt các mục sau:
- Xcode 16.2 trở lên
Đảm bảo rằng dự án của bạn đáp ứng các yêu cầu sau:
- Dự án của bạn phải nhắm đến các phiên bản nền tảng này trở lên:
- iOS 13
- macOS 10.15
- tvOS 13
- watchOS 7
- Dự án của bạn phải nhắm đến các phiên bản nền tảng này trở lên:
Thiết lập một thiết bị thực của Apple để chạy ứng dụng và hoàn tất các việc sau:
- Lấy Khoá xác thực thông báo đẩy của Apple cho tài khoản Apple Developer của bạn.
- Bật thông báo đẩy trong XCode trong phần App > Capabilities (Ứng dụng > Chức năng).
- Đăng nhập vào Firebase bằng Tài khoản Google của bạn.
Nếu chưa có dự án Xcode và chỉ muốn dùng thử một sản phẩm của Firebase, bạn có thể tải một trong các mẫu khởi động nhanh của chúng tôi xuống.
Tạo một dự án Firebase
Trước khi có thể thêm Firebase vào ứng dụng Apple, bạn cần tạo một dự án Firebase để kết nối với ứng dụng của mình. Hãy truy cập vào trang Tìm hiểu về các dự án Firebase để tìm hiểu thêm về các dự án Firebase.
Đăng ký ứng dụng của bạn với Firebase
Để sử dụng Firebase trong ứng dụng Apple, bạn cần đăng ký ứng dụng với dự án Firebase. Việc đăng ký ứng dụng thường được gọi là "thêm" ứng dụng vào dự án.
Chuyển đến bảng điều khiển Firebase.
Ở giữa trang tổng quan của dự án, hãy nhấp vào biểu tượng iOS+ để chạy quy trình thiết lập.
Nếu bạn đã thêm một ứng dụng vào dự án Firebase, hãy nhấp vào Thêm ứng dụng để hiển thị các lựa chọn về nền tảng.
Nhập mã nhận dạng gói của ứng dụng vào trường mã nhận dạng gói.
(Không bắt buộc) Nhập thông tin khác về ứng dụng: Biệt hiệu của ứng dụng và Mã App Store.
Nhấp vào Đăng ký ứng dụng.
Thêm tệp cấu hình Firebase
Nhấp vào Download GoogleService-Info.plist (Tải GoogleService-Info.plist xuống) để lấy tệp cấu hình Firebase của ứng dụng (
GoogleService-Info.plist
).Di chuyển tệp cấu hình vào thư mục gốc của dự án Xcode. Nếu được nhắc, hãy chọn thêm tệp cấu hình vào tất cả các mục tiêu.
Nếu có nhiều mã nhận dạng gói trong dự án, bạn phải liên kết từng mã nhận dạng gói với một ứng dụng đã đăng ký trong bảng điều khiển Firebase để mỗi ứng dụng có thể có tệp GoogleService-Info.plist
riêng.
Thêm SDK Firebase vào ứng dụng của bạn
Sử dụng Swift Package Manager để cài đặt và quản lý các phần phụ thuộc của Firebase.
- Trong Xcode, khi dự án ứng dụng của bạn đang mở, hãy chuyển đến File > Add Packages (Tệp > Thêm gói).
- Khi được nhắc, hãy thêm kho lưu trữ SDK Firebase cho các nền tảng của Apple:
- Chọn thư viện Firebase Cloud Messaging.
- Thêm cờ
-ObjC
vào mục Cờ trình liên kết khác trong chế độ cài đặt bản dựng của mục tiêu. - Để có trải nghiệm tối ưu với Firebase Cloud Messaging, bạn nên bật Google Analytics trong dự án Firebase và thêm Firebase SDK cho Google Analytics vào ứng dụng của mình. Bạn có thể chọn thư viện không thu thập IDFA hoặc có thu thập IDFA. Hãy xem phần Câu hỏi thường gặp của chúng tôi về cách sắp xếp mới nhất của các mô-đun trong Google Analytics cho SDK Firebase.
- Khi hoàn tất, Xcode sẽ tự động bắt đầu phân giải và tải các phần phụ thuộc của bạn xuống ở chế độ nền.
https://github.com/firebase/firebase-ios-sdk.git
Tải khoá xác thực APNs lên
Tải khoá xác thực APNs lên Firebase. Nếu bạn chưa có khoá xác thực APNs, hãy nhớ tạo một khoá trong Trung tâm thành viên của nhà phát triển Apple.
-
Trong dự án của bạn trên bảng điều khiển Firebase, hãy chọn biểu tượng bánh răng, chọn Project Settings (Cài đặt dự án), rồi chọn thẻ Cloud Messaging (Nhắn tin qua đám mây).
-
Trong phần Khoá xác thực APNs trong Cấu hình ứng dụng iOS, hãy nhấp vào nút Tải lên.
-
Duyệt đến vị trí mà bạn đã lưu khoá, chọn khoá đó rồi nhấp vào Mở. Thêm mã khoá cho khoá (có trong Trung tâm thành viên của nhà phát triển Apple) rồi nhấp vào Tải lên.
Khởi động Firebase trong ứng dụng của bạn
Bạn cần thêm mã khởi chạy Firebase vào ứng dụng của mình. Nhập mô-đun Firebase và định cấu hình một thực thể dùng chung như minh hoạ:
- Nhập mô-đun
FirebaseCore
trongUIApplicationDelegate
, cũng như mọi mô-đun Firebase khác mà uỷ quyền ứng dụng của bạn sử dụng. Ví dụ: để sử dụng Cloud Firestore và 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; // ...
- Định cấu hình một phiên bản dùng chung
FirebaseApp
trong phương thứcapplication(_:didFinishLaunchingWithOptions:)
của uỷ quyền ứng dụng: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];
- Nếu đang sử dụng SwiftUI, bạn phải tạo một uỷ quyền ứng dụng và đính kèm uỷ quyền đó vào cấu trúc
App
thông quaUIApplicationDelegateAdaptor
hoặcNSApplicationDelegateAdaptor
. Bạn cũng phải tắt tính năng thay thế phương thức uỷ quyền của ứng dụng. Để biết thêm thông tin, hãy xem hướng dẫn về SwiftUI.SwiftUI
@main struct YourApp: App { // register app delegate for Firebase setup @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate var body: some Scene { WindowGroup { NavigationView { ContentView() } } } }
Đăng ký nhận thông báo từ xa
Khi khởi động hoặc tại điểm mong muốn trong quy trình ứng dụng, hãy đăng ký ứng dụng của bạn để nhận thông báo từ xa. GọiregisterForRemoteNotifications
như minh hoạ:
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];
Đăng ký ứng dụng khách vào một chủ đề
Ứng dụng khách có thể đăng ký theo dõi bất kỳ chủ đề nào hiện có hoặc có thể tạo một chủ đề mới. Khi một ứng dụng khách đăng ký một tên chủ đề mới (tên chưa tồn tại cho dự án Firebase của bạn), một chủ đề mới có tên đó sẽ được tạo trong FCM và mọi ứng dụng khách đều có thể đăng ký chủ đề đó sau này.
Để đăng ký theo dõi một chủ đề, hãy gọi phương thức đăng ký từ luồng chính của ứng dụng (FCM không an toàn cho luồng). Nếu yêu cầu đăng ký ban đầu không thành công, FCM sẽ tự động thử lại. Đối với những trường hợp không thể hoàn tất quy trình đăng ký, quy trình đăng ký sẽ gửi một lỗi mà bạn có thể bắt trong trình xử lý hoàn tất như minh hoạ:
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"); }];
Lệnh gọi này đưa ra một yêu cầu không đồng bộ đến phần phụ trợ FCM và đăng ký ứng dụng khách vào chủ đề đã cho. Trước khi gọi subscribeToTopic:topic
, hãy đảm bảo rằng phiên bản ứng dụng khách đã nhận được mã đăng ký thông qua lệnh gọi lại didReceiveRegistrationToken
.
Mỗi khi ứng dụng khởi động, FCM sẽ đảm bảo rằng bạn đã đăng ký tất cả các chủ đề được yêu cầu. Để huỷ đăng ký, hãy gọi unsubscribeFromTopic:topic
và FCM sẽ huỷ đăng ký theo dõi chủ đề trong nền.
Nhận và xử lý thông báo theo chủ đề
FCM gửi thông báo theo chủ đề theo cách tương tự như các thông báo khác ở hạ lưu.
Triển khai application(_:didReceiveRemoteNotification:fetchCompletionHandler:)
như sau:
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); }
Tạo yêu cầu gửi
Sau khi tạo một chủ đề, bằng cách đăng ký các phiên bản ứng dụng khách vào chủ đề ở phía ứng dụng khách hoặc thông qua API máy chủ, bạn có thể gửi thông báo đến chủ đề đó. Nếu đây là lần đầu tiên bạn tạo yêu cầu gửi cho FCM, hãy xem hướng dẫn về môi trường máy chủ và FCM để biết thông tin quan trọng về bối cảnh và cách thiết lập.
Trong logic gửi ở phần phụ trợ, hãy chỉ định tên chủ đề mong muốn như minh hoạ:
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)
Tìm
// 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);
Kiến trúc chuyển trạng thái đại diện (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"
}
}
}
Lệnh 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
Để gửi thông báo đến một tổ hợp các chủ đề, hãy chỉ định một điều kiện. Đây là một biểu thức boolean chỉ định các chủ đề mục tiêu. Ví dụ: điều kiện sau đây sẽ gửi thông báo đến những thiết bị đã đăng ký TopicA
và TopicB
hoặc TopicC
:
"'TopicA' in topics && ('TopicB' in topics || 'TopicC' in topics)"
FCM trước tiên sẽ đánh giá mọi điều kiện trong dấu ngoặc đơn, sau đó đánh giá biểu thức từ trái sang phải. Trong biểu thức trên, người dùng đăng ký một chủ đề bất kỳ sẽ không nhận được thông báo. Tương tự, người dùng không đăng ký TopicA
sẽ không nhận được thông báo. Các tổ hợp này sẽ nhận được:
TopicA
vàTopicB
TopicA
vàTopicC
Bạn có thể thêm tối đa 5 chủ đề vào biểu thức có điều kiện.
Để gửi đến một điều kiện:
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)
Tìm
// 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);
Kiến trúc chuyển trạng thái đại diện (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",
}
}
}
Lệnh 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
Các bước tiếp theo
- Bạn có thể dùng máy chủ để đăng ký các phiên bản ứng dụng khách vào các chủ đề và thực hiện các tác vụ quản lý khác. Xem phần Quản lý các gói đăng ký chủ đề trên máy chủ.