Để 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.
Tạo dự án Firebase
-
Trong bảng điều khiển Firebase, hãy nhấp vào Thêm dự án.
-
Để thêm tài nguyên Firebase vào một dự án hiện có Google Cloud, hãy nhập tên dự án hoặc chọn dự án đó trong trình đơn thả xuống.
-
Để tạo một dự án mới, hãy nhập tên dự án. Bạn cũng có thể tuỳ ý chỉnh sửa mã dự án xuất hiện bên dưới tên dự án.
-
-
Nếu được nhắc, hãy xem xét và chấp nhận các điều khoản của Firebase.
-
Nhấp vào Tiếp tục.
-
(Không bắt buộc) Thiết lập Google Analytics cho dự án của bạn. Việc này giúp mang lại trải nghiệm tối ưu khi sử dụng các sản phẩm sau đây của Firebase: Firebase A/B Testing, Cloud Messaging, Crashlytics, In-App Messaging và Remote Config (bao gồm cả Cá nhân hoá).
Chọn một tài khoản Google Analytics hiện có hoặc tạo một tài khoản mới. Nếu bạn tạo tài khoản mới, hãy chọn Analyticsvị trí báo cáo, sau đó chấp nhận chế độ chia sẻ dữ liệu và Google Analyticsđiều khoản cho dự án của bạn.
-
Nhấp vào Tạo dự án (hoặc Thêm Firebase nếu bạn đang thêm Firebase vào một dự án Google Cloud hiện có).
Firebase tự động cung cấp tài nguyên cho dự án Firebase của bạn. Khi quá trình này hoàn tất, bạn sẽ được chuyển đến trang tổng quan về dự án Firebase của mình trong bảng điều khiể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.
Mã nhận dạng gói là gì và bạn có thể tìm thấy mã này ở đâu?
Mã nhận dạng gói giúp nhận dạng duy nhất một ứng dụng trong hệ sinh thái của Apple.
Tìm mã nhận dạng gói: mở dự án trong Xcode, chọn ứng dụng cấp cao nhất trong trình điều hướng dự án, sau đó chọn thẻ Chung.
Giá trị của trường Bundle Identifier (Giá trị nhận dạng gói) là mã nhận dạng gói (ví dụ:
com.yourcompany.yourproject
).Xin lưu ý rằng giá trị mã nhận dạng gói có phân biệt chữ hoa chữ thường và bạn không thể thay đổi giá trị này cho ứng dụng Firebase này sau khi ứng dụng được đăng ký với dự án Firebase của bạn.
(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.
Biệt hiệu ứng dụng và Mã trên App Store được dùng như thế nào trong Firebase?
Biệt hiệu của ứng dụng: Một giá trị nhận dạng nội bộ, thuận tiện và chỉ bạn mới thấy được trong bảng điều khiển Firebase
Mã App Store: Được Firebase Dynamic Links dùng để chuyển hướng người dùng đến trang App Store của bạn và được Google Analytics dùng để nhập sự kiện chuyển đổi vào Google Ads. Nếu ứng dụng của bạn chưa có mã nhận dạng trên App Store, thì bạn có thể thêm mã nhận dạng này sau trong phần Cài đặt dự án.
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
).Bạn cần biết những gì về tệp cấu hình này?
Tệp cấu hình Firebase chứa các giá trị nhận dạng duy nhất nhưng không bí mật của dự án và ứng dụng. Để tìm hiểu thêm về tệp cấu hình này, hãy truy cập vào phần Tìm hiểu về các dự án Firebase.
Bạn có thể tải tệp cấu hình Firebase xuống lại bất cứ lúc nào.
Đảm bảo rằng tên tệp cấu hình không có ký tự thừa, chẳng hạn như
(2)
.
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:import SwiftUI import FirebaseCore import FirebaseFirestore import FirebaseAuth // ...
import FirebaseCore import FirebaseFirestore import FirebaseAuth // ...
@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:// Use Firebase library to configure APIs FirebaseApp.configure()
// Use Firebase library to configure APIs FirebaseApp.configure()
// 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.@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ạ:
UNUserNotificationCenter.current().delegate = self let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound] UNUserNotificationCenter.current().requestAuthorization( options: authOptions, completionHandler: { _, _ in } ) application.registerForRemoteNotifications()
[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ạ:
Messaging.messaging().subscribe(toTopic: "weather") { error in print("Subscribed to weather topic") }
[[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:
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 }
- (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ạ:
// 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);
});
// 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);
# 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)
// 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)
// 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);
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:
// 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);
});
// 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);
# 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)
// 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)
// 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);
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ủ.