Catch up on everything announced at Firebase Summit, and learn how Firebase can help you accelerate app development and run your app with confidence. Learn More

ส่งข้อความไปยังอุปกรณ์หลายเครื่องบนแพลตฟอร์ม Apple

จัดทุกอย่างให้เป็นระเบียบอยู่เสมอด้วยคอลเล็กชัน บันทึกและจัดหมวดหมู่เนื้อหาตามค่ากำหนดของคุณ

Firebase Cloud Messaging มีสองวิธีในการกำหนดเป้าหมายข้อความไปยังอุปกรณ์หลายเครื่อง:

บทช่วยสอนนี้เน้นที่การส่งข้อความหัวข้อจากเซิร์ฟเวอร์แอปของคุณโดยใช้ Admin SDK หรือ REST API สำหรับ FCM และรับและจัดการข้อความเหล่านั้นในแอป Apple หน้านี้แสดงขั้นตอนทั้งหมดเพื่อให้บรรลุตามนี้ ตั้งแต่การตั้งค่าไปจนถึงการยืนยัน ดังนั้นอาจครอบคลุมขั้นตอนที่คุณดำเนินการไปแล้ว หากคุณได้ ตั้งค่าแอปไคลเอนต์ Apple สำหรับ FCM หรือดำเนินการตามขั้นตอนต่างๆ เพื่อ ส่งข้อความแรกของคุณ

เพิ่ม Firebase ในโครงการ Apple ของคุณ

ส่วนนี้ครอบคลุมถึงงานที่คุณอาจทำเสร็จแล้วหากคุณเปิดใช้ฟีเจอร์ Firebase อื่นๆ สำหรับแอปของคุณแล้ว สำหรับ FCM โดยเฉพาะ คุณจะต้อง อัปโหลดคีย์การตรวจสอบสิทธิ์ APN ของคุณ และ ลงทะเบียนสำหรับการแจ้งเตือนระยะไกล

ข้อกำหนดเบื้องต้น

  • ติดตั้งสิ่งต่อไปนี้:

    • Xcode 13.3.1 หรือใหม่กว่า
  • ตรวจสอบให้แน่ใจว่าโครงการของคุณตรงตามข้อกำหนดเหล่านี้:

    • โครงการของคุณต้องกำหนดเป้าหมายเวอร์ชันแพลตฟอร์มเหล่านี้หรือใหม่กว่า:
      • iOS 11
      • แมคโอเอส 10.13
      • tvOS 12
      • วอทช์โอเอส 6
  • ตั้งค่า อุปกรณ์ Apple จริง เพื่อเรียกใช้แอพของคุณ และทำงานเหล่านี้ให้เสร็จ:

    • รับรหัสการตรวจสอบสิทธิ์การแจ้งเตือนแบบพุชของ Apple สำหรับบัญชีนักพัฒนา Apple ของคุณ
    • เปิดใช้งานการแจ้งเตือนแบบพุชใน XCode ภายใต้ App > Capabilities

หากคุณยังไม่มีโครงการ Xcode และเพียงต้องการลองใช้ผลิตภัณฑ์ Firebase คุณสามารถดาวน์โหลดหนึ่งใน ตัวอย่าง การเริ่มต้นอย่างรวดเร็วของเรา

สร้างโครงการ Firebase

ก่อนที่คุณจะเพิ่ม Firebase ลงในแอป Apple คุณต้องสร้างโปรเจ็กต์ Firebase เพื่อเชื่อมต่อกับแอปของคุณ ไปที่ ทำความเข้าใจโครงการ Firebase เพื่อเรียนรู้เพิ่มเติมเกี่ยวกับโครงการ Firebase

ลงทะเบียนแอปของคุณกับ Firebase

หากต้องการใช้ Firebase ในแอป Apple คุณต้องลงทะเบียนแอปกับโปรเจ็กต์ Firebase การลงทะเบียนแอปมักเรียกว่า "การเพิ่ม" แอปของคุณในโครงการ

  1. ไปที่ คอนโซล Firebase

  2. ที่กึ่งกลางของหน้าภาพรวมโครงการ ให้คลิกไอคอน iOS+ เพื่อเปิดเวิร์กโฟลว์การตั้งค่า

    หากคุณเพิ่มแอปในโครงการ Firebase แล้ว ให้คลิก เพิ่มแอป เพื่อแสดงตัวเลือกแพลตฟอร์ม

  3. ป้อนรหัสชุดของแอปในช่อง รหัสชุด

  4. (ไม่บังคับ) ป้อนข้อมูลแอปอื่นๆ: ชื่อเล่นแอ ป และ App Store ID

  5. คลิก ลงทะเบียนแอป

เพิ่มไฟล์กำหนดค่า Firebase

  1. คลิก ดาวน์โหลด GoogleService-Info.plist เพื่อรับไฟล์กำหนดค่าแพลตฟอร์ม Firebase Apple ( GoogleService-Info.plist )

  2. ย้ายไฟล์กำหนดค่าของคุณไปที่รูทของโปรเจ็กต์ Xcode หากได้รับแจ้ง ให้เลือกเพื่อเพิ่มไฟล์กำหนดค่าไปยังเป้าหมายทั้งหมด

หากคุณมีรหัสกลุ่มหลายรหัสในโครงการ คุณต้องเชื่อมโยงรหัสกลุ่มแต่ละรายการกับแอปที่ลงทะเบียนในคอนโซล Firebase เพื่อให้แต่ละแอปมีไฟล์ GoogleService-Info.plist ของตัวเอง

เพิ่ม Firebase SDK ลงในแอปของคุณ

ใช้ Swift Package Manager เพื่อติดตั้งและจัดการการอ้างอิง Firebase

  1. ใน Xcode เมื่อโปรเจ็กต์แอปของคุณเปิดอยู่ ให้ไปที่ File > Add Packages
  2. เมื่อได้รับแจ้ง ให้เพิ่มที่เก็บ Firebase Apple platforms SDK:
  3.   https://github.com/firebase/firebase-ios-sdk
  4. เลือกไลบรารี Firebase Cloud Messaging
  5. เพื่อประสบการณ์ที่ดีที่สุดกับ Firebase Cloud Messaging เราขอแนะนำให้ เปิดใช้ Google Analytics ในโครงการ Firebase และเพิ่ม Firebase SDK สำหรับ Google Analytics ลงในแอปของคุณ คุณสามารถเลือกห้องสมุดที่ไม่มีการรวบรวม IDFA หรือมีการรวบรวม IDFA
  6. เมื่อเสร็จแล้ว Xcode จะเริ่มแก้ไขและดาวน์โหลดการอ้างอิงของคุณโดยอัตโนมัติในเบื้องหลัง

อัปโหลดคีย์การตรวจสอบสิทธิ์ APN ของคุณ

อัปโหลดคีย์การตรวจสอบสิทธิ์ APN ของคุณไปยัง Firebase หากคุณยังไม่มีคีย์การตรวจสอบสิทธิ์ APN โปรดสร้างคีย์ใน Apple Developer Member Center

  1. ภายในโครงการของคุณในคอนโซล Firebase เลือกไอคอนรูปเฟือง เลือก การตั้งค่าโครงการ จากนั้นเลือกแท็บ Cloud Messaging

  2. ใน คีย์การตรวจสอบสิทธิ์ APN ภายใต้ การกำหนดค่าแอป iOS ให้คลิกปุ่ม อัปโหลด

  3. เรียกดูตำแหน่งที่คุณบันทึกคีย์ เลือก และคลิก เปิด เพิ่ม ID คีย์สำหรับคีย์ (มีให้ใน Apple Developer Member Center ) แล้วคลิก อัปโหลด

เริ่มต้น Firebase ในแอปของคุณ

คุณจะต้องเพิ่มรหัสเริ่มต้นของ Firebase ในแอปพลิเคชันของคุณ นำเข้าโมดูล Firebase และกำหนดค่าอินสแตนซ์ที่ใช้ร่วมกันตามที่แสดง:

  1. นำเข้าโมดูล FirebaseCore ใน UIApplicationDelegate ของคุณ รวมถึง โมดูล Firebase อื่นๆ ที่ตัวแทนแอปของคุณใช้ ตัวอย่างเช่น หากต้องการใช้ Cloud Firestore และการรับรองความถูกต้อง:

    สวิฟต์

    import FirebaseCore
    import FirebaseFirestore
    import FirebaseAuth
    // ...
          

    วัตถุประสงค์-C

    @import FirebaseCore;
    @import FirebaseFirestore;
    @import FirebaseAuth;
    // ...
          
  2. กำหนดค่าอินสแตนซ์ที่ใช้ร่วมกันของ FirebaseApp ในแอปพลิเคชันผู้รับมอบสิทธิ์แอปของคุณ application(_:didFinishLaunchingWithOptions:) วิธีการ:

    สวิฟต์

    // Use Firebase library to configure APIs
    FirebaseApp.configure()

    วัตถุประสงค์-C

    // Use Firebase library to configure APIs
    [FIRApp configure];

ลงทะเบียนสำหรับการแจ้งเตือนระยะไกล

ไม่ว่าจะเมื่อเริ่มต้นหรือเมื่อถึงจุดที่ต้องการในโฟลว์ของแอปพลิเคชัน ให้ลงทะเบียนแอปของคุณสำหรับการแจ้งเตือนระยะไกล โทร registerForRemoteNotifications ดังที่แสดง:

สวิฟต์


UNUserNotificationCenter.current().delegate = self

let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
  options: authOptions,
  completionHandler: { _, _ in }
)

application.registerForRemoteNotifications()

วัตถุประสงค์-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 จะลองใหม่โดยอัตโนมัติ สำหรับกรณีที่การสมัครสมาชิกไม่สามารถดำเนินการให้เสร็จสมบูรณ์ การสมัครสมาชิกจะส่งข้อผิดพลาดที่คุณสามารถตรวจจับได้ในตัวจัดการการทำให้เสร็จสมบูรณ์ดังที่แสดง:

สวิฟต์

Messaging.messaging().subscribe(toTopic: "weather") { error in
  print("Subscribed to weather topic")
}

วัตถุประสงค์-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:) ดังที่แสดง:

สวิฟต์

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
}

วัตถุประสงค์-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 ของคุณ สำหรับข้อมูลเบื้องหลังและการตั้งค่าที่สำคัญ

ในตรรกะการส่งของคุณที่แบ็กเอนด์ ให้ระบุชื่อหัวข้อที่ต้องการตามที่แสดง:

โหนด 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);
  });

ชวา

// 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"
      }
   }
}

คำสั่งขด:

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

หากต้องการส่งข้อความไปยัง ชุด หัวข้อต่างๆ ให้ระบุ เงื่อนไข ซึ่งเป็นนิพจน์บูลีนที่ระบุหัวข้อเป้าหมาย ตัวอย่างเช่น เงื่อนไขต่อไปนี้จะส่งข้อความไปยังอุปกรณ์ที่สมัครใช้ TopicA และ TopicB หรือ TopicC :

"'TopicA' in topics && ('TopicB' in topics || 'TopicC' in topics)"

FCM จะประเมินเงื่อนไขใดๆ ในวงเล็บก่อน จากนั้นจึงประเมินนิพจน์จากซ้ายไปขวา ในนิพจน์ข้างต้น ผู้ใช้ที่สมัครรับข้อมูลในหัวข้อใดหัวข้อหนึ่งจะไม่ได้รับข้อความ ในทำนองเดียวกัน ผู้ใช้ที่ไม่ได้สมัครรับข้อมูล TopicA จะไม่ได้รับข้อความ ชุดค่าผสมเหล่านี้จะได้รับ:

  • TopicA และ TopicB
  • TopicA และ TopicC

คุณสามารถใส่หัวข้อในนิพจน์เงื่อนไขได้สูงสุดห้าหัวข้อ

หากต้องการส่งไปยังเงื่อนไข:

โหนด 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);
  });

ชวา

// 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",
    }
  }
}

คำสั่งขด:

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

ขั้นตอนถัดไป