ในการกำหนดเป้าหมายข้อความไปยังอุปกรณ์หลายเครื่อง ให้ใช้ ข้อความตามหัวข้อ ช่วงเวลานี้ ที่ช่วยให้คุณดำเนินการ ส่งข้อความไปยังอุปกรณ์หลายเครื่องที่เลือกเข้าร่วมหัวข้อเฉพาะได้
บทแนะนำนี้มุ่งเน้นไปที่การส่งข้อความตามหัวข้อจากเซิร์ฟเวอร์แอปของคุณโดยใช้ Admin SDK หรือ API ของ REST FCM แล้วรับและจัดการคำสั่งซื้อ ในแอป Apple หน้านี้จะแสดงขั้นตอนทั้งหมดในการบรรลุเป้าหมายนี้ ตั้งแต่การตั้งค่าไปจนถึง ซึ่งอาจครอบคลุมถึงขั้นตอนที่คุณได้ดำเนินการไปแล้วหากคุณมี ตั้งค่าแอปไคลเอ็นต์ของ Apple สำหรับ FCM หรือทำตามขั้นตอนในการส่งข้อความแรกของคุณ
เพิ่ม Firebase ลงในโปรเจ็กต์ Apple
ส่วนนี้ครอบคลุมงานที่คุณอาจทำเสร็จแล้วหากเปิดใช้แล้ว ฟีเจอร์อื่นๆ ของ Firebase สำหรับแอป สำหรับ FCM คุณสามารถ จำเป็นต้อง อัปโหลดคีย์การตรวจสอบสิทธิ์ APNs และ ลงทะเบียนรับการแจ้งเตือนระยะไกล
ข้อกำหนดเบื้องต้น
ติดตั้งสิ่งต่อไปนี้
- Xcode 15.2 ขึ้นไป
ตรวจสอบว่าโปรเจ็กต์เป็นไปตามข้อกำหนดต่อไปนี้
- โปรเจ็กต์ของคุณต้องกำหนดเป้าหมายเวอร์ชันแพลตฟอร์มต่อไปนี้หรือเวอร์ชันที่ใหม่กว่า
- iOS 13
- macOS 10.15
- TVOS 13
- WatchOS 7
- โปรเจ็กต์ของคุณต้องกำหนดเป้าหมายเวอร์ชันแพลตฟอร์มต่อไปนี้หรือเวอร์ชันที่ใหม่กว่า
ตั้งค่าอุปกรณ์ Apple จริงเพื่อเรียกใช้แอป แล้วทำงานต่อไปนี้ให้เสร็จ
- รับคีย์การตรวจสอบสิทธิ์ข้อความ Push ของ Apple สำหรับ บัญชีนักพัฒนาแอป Apple
- เปิดใช้ข้อความ Push ใน XCode ในส่วน App > ความสามารถ
- ลงชื่อเข้าใช้ Firebase โดยใช้ บัญชี Google
หากยังไม่มีโปรเจ็กต์ Xcode และต้องการลองใช้ Firebase คุณสามารถดาวน์โหลดตัวอย่างการเริ่มต้นอย่างรวดเร็วของเราได้
สร้างโปรเจ็กต์ Firebase
คุณต้องสร้าง Firebase ก่อนจึงจะเพิ่ม Firebase ลงในแอป Apple ได้ เพื่อเชื่อมต่อกับแอปของคุณ ไปที่เว็บไซต์ ทำความเข้าใจโปรเจ็กต์ Firebase เพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับ โปรเจ็กต์ Firebase
ลงทะเบียนแอปด้วย Firebase
หากต้องการใช้ Firebase ในแอป Apple คุณต้องลงทะเบียนแอปด้วย โปรเจ็กต์ Firebase การลงทะเบียนแอปมักเรียกว่า "การเพิ่ม" แอปของคุณไปยัง
ไปที่คอนโซลของ Firebase
ที่ตรงกลางของหน้าภาพรวมโปรเจ็กต์ ให้คลิกไอคอน iOS+ เพื่อเปิดเวิร์กโฟลว์การตั้งค่า
หากคุณเพิ่มแอปลงในโปรเจ็กต์ Firebase แล้ว ให้คลิกเพิ่มแอป เพื่อแสดงตัวเลือกแพลตฟอร์ม
ป้อนรหัสชุดของแอปในช่องรหัสแพ็กเกจ
(ไม่บังคับ) ป้อนข้อมูลอื่นๆ ของแอป ชื่อเล่นแอปและรหัส App Store
คลิกลงทะเบียนแอป
เพิ่มไฟล์การกำหนดค่า Firebase
คลิก Download GoogleService-Info.plist เพื่อรับ Firebase Apple ไฟล์การกำหนดค่าแพลตฟอร์ม (
GoogleService-Info.plist
)ย้ายไฟล์การกำหนดค่าไปยังรูทของโปรเจ็กต์ Xcode หากได้รับข้อความแจ้ง เลือกเพื่อเพิ่มไฟล์การกำหนดค่าไปยังเป้าหมายทั้งหมด
หากมีรหัสชุดหลายรายการในโปรเจ็กต์ คุณต้องเชื่อมโยงแพ็กเกจแต่ละรายการ
ด้วยแอปที่ลงทะเบียนแล้วในคอนโซล Firebase เพื่อให้แต่ละแอปมี
ไฟล์ GoogleService-Info.plist
ของตัวเอง
เพิ่ม Firebase SDK ลงในแอป
ใช้ Swift Package Manager เพื่อติดตั้งและจัดการทรัพยากร Dependency ของ Firebase
- เปิดโปรเจ็กต์แอปใน Xcode แล้วไปที่ไฟล์ > เพิ่มแพ็กเกจ
- เมื่อได้รับข้อความแจ้ง ให้เพิ่มที่เก็บ SDK สำหรับแพลตฟอร์ม Firebase ของ Apple ดังนี้
- เลือกไลบรารี Firebase Cloud Messaging
- เพิ่มแฟล็ก
-ObjC
ลงในส่วนแฟล็ก Linker อื่นๆ ของการตั้งค่าบิลด์ของเป้าหมาย - เราขอแนะนำเพื่อประสบการณ์การใช้งาน Firebase Cloud Messaging ที่ดีที่สุด กำลังเปิดใช้ Google Analytics ในโปรเจ็กต์ Firebase และเพิ่ม Firebase SDK สำหรับ Google Analytics ลงในแอป คุณสามารถ ให้เลือกไลบรารีที่ไม่มีการรวบรวม IDFA หรือมีคอลเล็กชัน IDFA
- เมื่อเสร็จแล้ว Xcode จะเริ่มแก้ปัญหาและดาวน์โหลด ทรัพยากร Dependency ในเบื้องหลัง
https://github.com/firebase/firebase-ios-sdk.git
อัปโหลดคีย์การตรวจสอบสิทธิ์ APNs
อัปโหลดคีย์การตรวจสอบสิทธิ์ APN ไปยัง Firebase หากคุณยังไม่มีคีย์การตรวจสอบสิทธิ์ APNs โปรดสร้างคีย์ใน Apple Developer Member Center
-
ภายในโปรเจ็กต์ในคอนโซล Firebase ให้เลือก ไอคอนรูปเฟือง, เลือก การตั้งค่าโปรเจ็กต์ แล้วเลือก แท็บการรับส่งข้อความในระบบคลาวด์
-
ในคีย์การตรวจสอบสิทธิ์ AAP ในส่วนการกำหนดค่าแอป iOS ให้คลิกอัปโหลด
-
เรียกดูตำแหน่งที่คุณบันทึกกุญแจไว้ จากนั้นเลือกคีย์แล้วคลิก เปิด เพิ่มรหัสคีย์สำหรับคีย์ (มีอยู่ใน Apple Developer Member Center) แล้วคลิก อัปโหลด
เริ่มต้น Firebase ในแอป
คุณจะต้องเพิ่มโค้ดการเริ่มต้น Firebase ลงในแอปพลิเคชัน นำเข้า โมดูล Firebase และกำหนดค่าอินสแตนซ์ที่แชร์ตามที่แสดงด้านล่าง
- นำเข้าโมดูล
FirebaseCore
ในUIApplicationDelegate
และอื่นๆ โมดูล Firebase ที่ผู้รับมอบสิทธิ์แอปใช้ ตัวอย่างเช่น หากต้องการใช้ Cloud Firestore และ 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; // ...
- กําหนดค่า
FirebaseApp
อินสแตนซ์ที่แชร์ใน เมธอดapplication(_:didFinishLaunchingWithOptions:)
: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];
- หากใช้ SwiftUI คุณต้องสร้างการมอบสิทธิ์แอปพลิเคชันและแนบการมอบสิทธิ์
ไปยังโครงสร้าง
App
ของคุณผ่านUIApplicationDelegateAdaptor
หรือNSApplicationDelegateAdaptor
คุณต้องปิดใช้ SWizzing ที่มอบสิทธิ์ของแอปด้วย สำหรับ สำหรับข้อมูลเพิ่มเติม โปรดดูวิธีการของ SwiftUISwiftUI
@main struct YourApp: App { // register app delegate for Firebase setup @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate var body: some Scene { WindowGroup { NavigationView { ContentView() } } } }
ลงทะเบียนรับการแจ้งเตือนจากระยะไกล
ไม่ว่าจะเมื่อเริ่มต้นระบบ หรือที่จุดที่ต้องการในขั้นตอนการทำงานของแอปพลิเคชัน ลงทะเบียนแอปสำหรับการแจ้งเตือนระยะไกล โทรregisterForRemoteNotifications
ตามที่แสดง:
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];
สมัครรับข้อมูลหัวข้อในแอปไคลเอ็นต์
แอปไคลเอ็นต์สามารถสมัครรับข้อมูลหัวข้อที่มีอยู่ หรือสามารถสร้างหัวข้อใหม่ หัวข้อ เมื่อแอปไคลเอ็นต์สมัครรับชื่อหัวข้อใหม่ (ประเภทที่ สำหรับโปรเจ็กต์ Firebase ของคุณ) หัวข้อใหม่ในชื่อนี้คือ ที่สร้างใน FCM และลูกค้าทุกรายสามารถสมัครใช้บริการในภายหลังได้
หากต้องการสมัครรับข้อมูลหัวข้อ ให้เลือกวิธีสมัครรับข้อมูล จากเทรดหลักของแอปพลิเคชัน (FCM ไม่ปลอดภัยของเทรด) หากส่งคำขอเพื่อสมัครใช้บริการไม่สำเร็จในตอนต้น FCM จะพยายามซ้ำโดยอัตโนมัติ ในกรณีที่ไม่สามารถสมัครใช้บริการให้เสร็จสมบูรณ์ได้ การสมัครใช้บริการดังกล่าวเกิดข้อผิดพลาด ในเครื่องจัดการการทำงานเสร็จสมบูรณ์ดังที่แสดง
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"); }];
การโทรครั้งนี้ทำให้
คำขอแบบอะซิงโครนัสไปยังแบ็กเอนด์ FCM และสมัครใช้บริการไคลเอ็นต์ให้
หัวข้อที่กำหนด ก่อนโทรหา subscribeToTopic:topic
โปรดตรวจสอบว่า
อินสแตนซ์แอปของไคลเอ็นต์ได้รับโทเค็นการลงทะเบียนแล้วผ่านทาง
โทรกลับ didReceiveRegistrationToken
ทุกครั้งที่แอปเริ่มทำงาน
FCM ตรวจสอบว่าได้สมัครรับข้อมูลหัวข้อที่ขอทั้งหมดแล้ว ถึง
ยกเลิกการสมัคร โทร unsubscribeFromTopic:topic
และ FCM ยกเลิกการสมัครรับข่าวสารจากหัวข้อในเบื้องหลัง
รับและจัดการข้อความตามหัวข้อ
FCM ส่งข้อความหัวข้อในลักษณะเดียวกับดาวน์สตรีมอื่นๆ ข้อความ
นำ application(_:didReceiveRemoteNotification:fetchCompletionHandler:)
ไปใช้
ดังต่อไปนี้
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); }
สร้างคำขอส่งคำขอ
หลังจากสร้างหัวข้อแล้ว ไม่ว่าจะด้วยการสมัครใช้บริการอินสแตนซ์แอปไคลเอ็นต์ หัวข้อในฝั่งไคลเอ็นต์หรือผ่าน API ของเซิร์ฟเวอร์ คุณสามารถส่งข้อความไปยัง หัวข้อ หากนี่เป็นครั้งแรกที่คุณสร้างคำขอสำหรับ FCM ดูคู่มือเพื่อ สภาพแวดล้อมของเซิร์ฟเวอร์และ FCM สำหรับ ความเป็นมาที่สำคัญและข้อมูลการตั้งค่า
ระบุชื่อหัวข้อที่ต้องการในตรรกะการส่งบนแบ็กเอนด์ ดังต่อไปนี้
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:
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
หากต้องการส่งข้อความไปยังกลุ่มหัวข้อ
ระบุ condition ซึ่งเป็นนิพจน์บูลีนที่ระบุพารามิเตอร์
หัวข้อเป้าหมาย ตัวอย่างเช่น เงื่อนไขต่อไปนี้จะส่งข้อความถึง
อุปกรณ์ที่สมัครใช้บริการ TopicA
และ TopicB
หรือ TopicC
:
"'TopicA' in topics && ('TopicB' in topics || 'TopicC' in topics)"
FCM จะประเมินเงื่อนไขในวงเล็บก่อน จากนั้นจึงประเมิน
นิพจน์จากซ้ายไปขวา ในนิพจน์ข้างต้น ผู้ใช้สมัครรับข้อมูล
หัวข้อใดหัวข้อหนึ่งไม่ได้รับข้อความ ในทำนองเดียวกัน ผู้ใช้ที่ไม่
การติดตาม TopicA
ไม่ได้รับข้อความ การผสมผสานเหล่านี้
รับเลย
TopicA
และTopicB
TopicA
และTopicC
คุณสามารถรวมหัวข้อไว้ในนิพจน์แบบมีเงื่อนไขได้สูงสุด 5 หัวข้อ
วิธีส่งไปยังเงื่อนไข
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:
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
ขั้นตอนถัดไป
- คุณสามารถใช้เซิร์ฟเวอร์ของคุณเพื่อสมัครรับข้อมูลอินสแตนซ์ของแอปไคลเอ็นต์สำหรับหัวข้อและ ทำงานด้านการจัดการอื่นๆ โปรดดู จัดการการสมัครรับข้อมูลตามหัวข้อบนเซิร์ฟเวอร์