หน้านี้ได้รับการแปลโดย Cloud Translation API
Switch to English

ส่งข้อความไปยังอุปกรณ์หลายเครื่อง

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

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

ตั้งค่า SDK

ส่วนนี้อาจครอบคลุมขั้นตอนที่คุณทำเสร็จแล้วหากคุณ ตั้งค่าแอปไคลเอ็นต์ JavaScript สำหรับ FCM หรือทำตามขั้นตอนต่างๆเพื่อ รับข้อความ

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

เพิ่ม Firebase ในโปรเจ็กต์ JavaScript ของคุณ หากยังไม่ได้ ทำ

ดึงวัตถุส่งข้อความ

// Retrieve Firebase Messaging object.
const messaging = firebase.messaging();

เข้าถึงโทเค็นการลงทะเบียน

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

โทเค็นการลงทะเบียนอาจเปลี่ยนแปลงเมื่อ:

  • เว็บแอปจะลบโทเค็นการลงทะเบียน
  • ผู้ใช้ล้างข้อมูลเบราว์เซอร์ ในกรณีนี้ให้เรียก getToken เพื่อดึงโทเค็นใหม่

ดึงโทเค็นการลงทะเบียนปัจจุบัน

เมื่อคุณต้องการดึงโทเค็นปัจจุบันให้เรียกใช้ getToken หากไม่ได้รับอนุญาตการแจ้งเตือนวิธีนี้จะขอสิทธิ์การแจ้งเตือนจากผู้ใช้ มิฉะนั้นจะส่งคืนโทเค็นหรือปฏิเสธสัญญาเนื่องจากข้อผิดพลาด

บริการส่งข้อความต้องการไฟล์ firebase-messaging-sw.js เว้นแต่คุณจะมีไฟล์ firebase-messaging-sw.js แล้วให้สร้างไฟล์เปล่าที่มีชื่อนั้นและวางไว้ในรากของโดเมนของคุณก่อนที่จะดึงโทเค็น คุณสามารถเพิ่มเนื้อหาที่มีความหมายลงในไฟล์ได้ในขั้นตอนการตั้งค่าไคลเอ็นต์ในภายหลัง

ในการดึงโทเค็นปัจจุบัน:

// Get Instance ID token. Initially this makes a network call, once retrieved
// subsequent calls to getToken will return from cache.
messaging.getToken().then((currentToken) => {
  if (currentToken) {
    sendTokenToServer(currentToken);
    updateUIForPushEnabled(currentToken);
  } else {
    // Show permission request.
    console.log('No Instance ID token available. Request permission to generate one.');
    // Show permission UI.
    updateUIForPushPermissionRequired();
    setTokenSentToServer(false);
  }
}).catch((err) => {
  console.log('An error occurred while retrieving token. ', err);
  showToken('Error retrieving Instance ID token. ', err);
  setTokenSentToServer(false);
});

ตรวจสอบการรีเฟรชโทเค็น

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

// Callback fired if Instance ID token is updated.
messaging.onTokenRefresh(() => {
  messaging.getToken().then((refreshedToken) => {
    console.log('Token refreshed.');
    // Indicate that the new Instance ID token has not yet been sent to the
    // app server.
    setTokenSentToServer(false);
    // Send Instance ID token to app server.
    sendTokenToServer(refreshedToken);
    // ...
  }).catch((err) => {
    console.log('Unable to retrieve refreshed token ', err);
    showToken('Unable to retrieve refreshed token ', err);
  });
});

หลังจากที่คุณได้รับโทเค็นแล้วให้ส่งไปยังเซิร์ฟเวอร์แอปของคุณและจัดเก็บโดยใช้วิธีการที่คุณต้องการ คุณสามารถใช้ Instance ID server API เพื่อ รับข้อมูลเกี่ยวกับการสมัครสมาชิก

สมัครสมาชิกแอปไคลเอนต์สำหรับหัวข้อ

ด้วยโทเค็นการลงทะเบียนและชื่อหัวข้อคุณสามารถเพิ่มโทเค็นในหัวข้อโดยใช้ API เซิร์ฟเวอร์ Google Instance ID เรียกใช้ Instance ID API ที่จุดสิ้นสุดนี้โดยระบุโทเค็นการลงทะเบียนของอินสแตนซ์ของแอปและชื่อหัวข้อ:

  https://iid.googleapis.com/iid/v1/<REGISTRATION_TOKEN>/rel/topics/<TOPIC_NAME>
 

ในการสมัครใช้งานอินสแตนซ์ของแอปในหัวข้อที่ชื่อว่า "movies" ให้ส่งคำขอ POST ต่อไปนี้จากเซิร์ฟเวอร์ของคุณไปยังปลายทางโดยเพิ่มรหัสเซิร์ฟเวอร์ API ของคุณในส่วนหัว authorizaton ดังที่แสดง:

 https://iid.googleapis.com/iid/v1/nKctODamlM4:CKrh_PC8kIb7O...clJONHoA/rel/topics/movies
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA
 

อย่า ส่งคำขอประเภทนี้จากไคลเอนต์เนื่องจากความไวของคีย์เซิร์ฟเวอร์

คำขอที่ประสบความสำเร็จส่งคืน HTTP 200 OK สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการตอบสนองข้อผิดพลาดและวิธีการส่งคำขอเป็นกลุ่มโปรดดูที่ สร้างแผนที่ความสัมพันธ์สำหรับอินสแตนซ์ของแอป

คุณสามารถส่งรายการโทเค็นการลงทะเบียนไปยังวิธีการสมัครสมาชิก Firebase Admin SDK เพื่อสมัครใช้งานอุปกรณ์ที่เกี่ยวข้องกับหัวข้อ:

Node.js

 // These registration tokens come from the client FCM SDKs.
var registrationTokens = [
  'YOUR_REGISTRATION_TOKEN_1',
  // ...
  'YOUR_REGISTRATION_TOKEN_n'
];

// Subscribe the devices corresponding to the registration tokens to the
// topic.
admin.messaging().subscribeToTopic(registrationTokens, topic)
  .then(function(response) {
    // See the MessagingTopicManagementResponse reference documentation
    // for the contents of response.
    console.log('Successfully subscribed to topic:', response);
  })
  .catch(function(error) {
    console.log('Error subscribing to topic:', error);
  });
 

ชวา

 // These registration tokens come from the client FCM SDKs.
List<String> registrationTokens = Arrays.asList(
    "YOUR_REGISTRATION_TOKEN_1",
    // ...
    "YOUR_REGISTRATION_TOKEN_n"
);

// Subscribe the devices corresponding to the registration tokens to the
// topic.
TopicManagementResponse response = FirebaseMessaging.getInstance().subscribeToTopic(
    registrationTokens, topic);
// See the TopicManagementResponse reference documentation
// for the contents of response.
System.out.println(response.getSuccessCount() + " tokens were subscribed successfully");
 

หลาม

 # These registration tokens come from the client FCM SDKs.
registration_tokens = [
    'YOUR_REGISTRATION_TOKEN_1',
    # ...
    'YOUR_REGISTRATION_TOKEN_n',
]

# Subscribe the devices corresponding to the registration tokens to the
# topic.
response = messaging.subscribe_to_topic(registration_tokens, topic)
# See the TopicManagementResponse reference documentation
# for the contents of response.
print(response.success_count, 'tokens were subscribed successfully')
 

ไป

 // These registration tokens come from the client FCM SDKs.
registrationTokens := []string{
	"YOUR_REGISTRATION_TOKEN_1",
	// ...
	"YOUR_REGISTRATION_TOKEN_n",
}

// Subscribe the devices corresponding to the registration tokens to the
// topic.
response, err := client.SubscribeToTopic(ctx, registrationTokens, topic)
if err != nil {
	log.Fatalln(err)
}
// See the TopicManagementResponse reference documentation
// for the contents of response.
fmt.Println(response.SuccessCount, "tokens were subscribed successfully")
 

ค#

 // These registration tokens come from the client FCM SDKs.
var registrationTokens = new List<string>()
{
    "YOUR_REGISTRATION_TOKEN_1",
    // ...
    "YOUR_REGISTRATION_TOKEN_n",
};

// Subscribe the devices corresponding to the registration tokens to the
// topic
var response = await FirebaseMessaging.DefaultInstance.SubscribeToTopicAsync(
    registrationTokens, topic);
// See the TopicManagementResponse reference documentation
// for the contents of response.
Console.WriteLine($"{response.SuccessCount} tokens were subscribed successfully"); 

Admin FCM API ยังช่วยให้คุณสามารถยกเลิกการสมัครอุปกรณ์จากหัวข้อโดยส่งโทเค็นการลงทะเบียนไปยังวิธีการที่เหมาะสม:

Node.js

 // These registration tokens come from the client FCM SDKs.
var registrationTokens = [
  'YOUR_REGISTRATION_TOKEN_1',
  // ...
  'YOUR_REGISTRATION_TOKEN_n'
];

// Unsubscribe the devices corresponding to the registration tokens from
// the topic.
admin.messaging().unsubscribeFromTopic(registrationTokens, topic)
  .then(function(response) {
    // See the MessagingTopicManagementResponse reference documentation
    // for the contents of response.
    console.log('Successfully unsubscribed from topic:', response);
  })
  .catch(function(error) {
    console.log('Error unsubscribing from topic:', error);
  });
 

ชวา

 // These registration tokens come from the client FCM SDKs.
List<String> registrationTokens = Arrays.asList(
    "YOUR_REGISTRATION_TOKEN_1",
    // ...
    "YOUR_REGISTRATION_TOKEN_n"
);

// Unsubscribe the devices corresponding to the registration tokens from
// the topic.
TopicManagementResponse response = FirebaseMessaging.getInstance().unsubscribeFromTopic(
    registrationTokens, topic);
// See the TopicManagementResponse reference documentation
// for the contents of response.
System.out.println(response.getSuccessCount() + " tokens were unsubscribed successfully");
 

หลาม

 # These registration tokens come from the client FCM SDKs.
registration_tokens = [
    'YOUR_REGISTRATION_TOKEN_1',
    # ...
    'YOUR_REGISTRATION_TOKEN_n',
]

# Unubscribe the devices corresponding to the registration tokens from the
# topic.
response = messaging.unsubscribe_from_topic(registration_tokens, topic)
# See the TopicManagementResponse reference documentation
# for the contents of response.
print(response.success_count, 'tokens were unsubscribed successfully')
 

ไป

 // These registration tokens come from the client FCM SDKs.
registrationTokens := []string{
	"YOUR_REGISTRATION_TOKEN_1",
	// ...
	"YOUR_REGISTRATION_TOKEN_n",
}

// Unsubscribe the devices corresponding to the registration tokens from
// the topic.
response, err := client.UnsubscribeFromTopic(ctx, registrationTokens, topic)
if err != nil {
	log.Fatalln(err)
}
// See the TopicManagementResponse reference documentation
// for the contents of response.
fmt.Println(response.SuccessCount, "tokens were unsubscribed successfully")
 

ค#

 // These registration tokens come from the client FCM SDKs.
var registrationTokens = new List<string>()
{
    "YOUR_REGISTRATION_TOKEN_1",
    // ...
    "YOUR_REGISTRATION_TOKEN_n",
};

// Unsubscribe the devices corresponding to the registration tokens from the
// topic
var response = await FirebaseMessaging.DefaultInstance.UnsubscribeFromTopicAsync(
    registrationTokens, topic);
// See the TopicManagementResponse reference documentation
// for the contents of response.
Console.WriteLine($"{response.SuccessCount} tokens were unsubscribed successfully"); 

วิธี subscribeToTopic() และ unsubscribeFromTopic() ส่งผลให้วัตถุมีการตอบสนองจาก FCM ประเภทการส่งคืนมีรูปแบบเดียวกันโดยไม่คำนึงถึงจำนวนโทเค็นการลงทะเบียนที่ระบุในคำขอ

ในกรณีที่เกิดข้อผิดพลาด (การพิสูจน์ตัวตนล้มเหลวโทเค็นไม่ถูกต้องหรือหัวข้อ ฯลฯ ) วิธีการเหล่านี้ส่งผลให้เกิดข้อผิดพลาด สำหรับรายการรหัสข้อผิดพลาดทั้งหมดรวมถึงคำอธิบายและขั้นตอนการแก้ปัญหาโปรดดู ข้อผิดพลาดของ Admin FCM API

รับและจัดการข้อความหัวข้อ

ลักษณะการทำงานของข้อความจะแตกต่างกันไปขึ้นอยู่กับว่าเพจนั้นอยู่เบื้องหน้า (มีโฟกัส) หรืออยู่เบื้องหลังซ่อนอยู่หลังแท็บอื่นหรือปิดสนิท ในทุกกรณีเพจต้องจัดการกับการเรียกกลับ onMessage แต่ในกรณีพื้นหลังคุณอาจต้องจัดการ setBackgroundMessageHandler หรือกำหนดค่าการแจ้งเตือนการแสดงผลเพื่ออนุญาตให้ผู้ใช้นำเว็บแอปของคุณไปที่เบื้องหน้า

สถานะแอป การแจ้งเตือน ข้อมูล ทั้งสอง
เบื้องหน้า onMessage onMessage onMessage
ภูมิหลัง (พนักงานบริการ) การแจ้งเตือนที่แสดงโดย SDK setBackgroundMessageHandler การแจ้งเตือนที่แสดงโดย SDK

จัดการข้อความเมื่อเว็บแอปของคุณอยู่เบื้องหน้า

ในการรับเหตุการณ์ onMessage แอปของคุณต้องกำหนด Firebase Messaging Service firebase-messaging-sw.js หรือคุณสามารถระบุพนักงานบริการที่มีอยู่โดยใช้ useServiceWorker

// Give the service worker access to Firebase Messaging.
// Note that you can only use Firebase Messaging here, other Firebase libraries
// are not available in the service worker.
importScripts('https://www.gstatic.com/firebasejs/7.17.1/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/7.17.1/firebase-messaging.js');

// Initialize the Firebase app in the service worker by passing in
// your app's Firebase config object.
// https://firebase.google.com/docs/web/setup#config-object
firebase.initializeApp({
  apiKey: 'api-key',
  authDomain: 'project-id.firebaseapp.com',
  databaseURL: 'https://project-id.firebaseio.com',
  projectId: 'project-id',
  storageBucket: 'project-id.appspot.com',
  messagingSenderId: 'sender-id',
  appId: 'app-id',
  measurementId: 'G-measurement-id',
});

// Retrieve an instance of Firebase Messaging so that it can handle background
// messages.
const messaging = firebase.messaging();

เมื่อแอปของคุณอยู่เบื้องหน้า (ผู้ใช้กำลังดูหน้าเว็บของคุณ) คุณสามารถรับข้อมูลและเพย์โหลดการแจ้งเตือนได้โดยตรงในหน้า

// Handle incoming messages. Called when:
// - a message is received while the app has focus
// - the user clicks on an app notification created by a service worker
//   `messaging.setBackgroundMessageHandler` handler.
messaging.onMessage((payload) => {
  console.log('Message received. ', payload);
  // ...
});

จัดการข้อความเมื่อเว็บแอปของคุณอยู่เบื้องหลัง

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

การตั้งค่าตัวเลือกการแจ้งเตือนในคำขอส่ง

สำหรับข้อความแจ้งเตือนที่ส่งจากเซิร์ฟเวอร์แอป FCM JavaScript API รองรับคีย์ fcm_options.link โดยทั่วไปจะตั้งค่าเป็นเพจในเว็บแอปของคุณ:

 https://fcm.googleapis.com//v1/projects/<YOUR-PROJECT-ID>/messages:send
Content-Type: application/json
Authorization: bearer <YOUR-ACCESS-TOKEN>

{
  "message": {
    "topic": "matchday"
    "notification": {
      "title": "Background Message Title",
      "body": "Background message body"
    },
    "webpush": {
      "fcm_options": {
        "link": "https://dummypage.com"
      }
    }
  }
}
 

หากค่าลิงก์ชี้ไปที่หน้าที่เปิดอยู่แล้วในแท็บเบราว์เซอร์การคลิกที่การแจ้งเตือนจะนำแท็บนั้นมาไว้ที่พื้นหน้า หากหน้ายังไม่เปิดการคลิกการแจ้งเตือนจะเปิดหน้าในแท็บใหม่

เนื่องจากข้อความข้อมูลไม่รองรับ fcm_options.link ขอแนะนำให้เพิ่มเพย์โหลดการแจ้งเตือนในข้อความข้อมูลทั้งหมด หรือคุณสามารถจัดการการแจ้งเตือนโดยใช้พนักงานบริการ

สำหรับคำอธิบายเกี่ยวกับความแตกต่างระหว่างการแจ้งเตือนและข้อความข้อมูลโปรดดู ประเภทข้อความ

การตั้งค่าตัวเลือกการแจ้งเตือนในพนักงานบริการ

สำหรับข้อความข้อมูลคุณสามารถตั้งค่าตัวเลือกการแจ้งเตือนในพนักงานบริการ ขั้นแรกเริ่มต้นแอปของคุณในพนักงานบริการ:

// Give the service worker access to Firebase Messaging.
// Note that you can only use Firebase Messaging here, other Firebase libraries
// are not available in the service worker.
importScripts('https://www.gstatic.com/firebasejs/7.17.1/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/7.17.1/firebase-messaging.js');

// Initialize the Firebase app in the service worker by passing in
// your app's Firebase config object.
// https://firebase.google.com/docs/web/setup#config-object
firebase.initializeApp({
  apiKey: 'api-key',
  authDomain: 'project-id.firebaseapp.com',
  databaseURL: 'https://project-id.firebaseio.com',
  projectId: 'project-id',
  storageBucket: 'project-id.appspot.com',
  messagingSenderId: 'sender-id',
  appId: 'app-id',
  measurementId: 'G-measurement-id',
});

// Retrieve an instance of Firebase Messaging so that it can handle background
// messages.
const messaging = firebase.messaging();

ในการตั้งค่าตัวเลือกให้เรียก setBackgroundMessageHandler ใน firebase-messaging-sw.js ในตัวอย่างนี้เราสร้างการแจ้งเตือนด้วยช่องชื่อเนื้อหาและไอคอน

messaging.setBackgroundMessageHandler(function(payload) {
  console.log('[firebase-messaging-sw.js] Received background message ', payload);
  // Customize notification here
  const notificationTitle = 'Background Message Title';
  const notificationOptions = {
    body: 'Background Message body.',
    icon: '/firebase-logo.png'
  };

  return self.registration.showNotification(notificationTitle,
    notificationOptions);
});

สร้างคำขอส่ง

จากฝั่งเซิร์ฟเวอร์การส่งข้อความไปยังหัวข้อ Firebase Cloud Messaging นั้นคล้ายกับการส่งข้อความไปยังอุปกรณ์แต่ละเครื่องหรือไปยังกลุ่มผู้ใช้ เซิร์ฟเวอร์แอปตั้งค่า to สำคัญที่มีค่าเช่น /topics/yourTopic นักพัฒนาสามารถเลือกชื่อหัวข้อใด ๆ ที่ตรงกับนิพจน์ทั่วไป: "/topics/[a-zA-Z0-9-_.~%]+"

หัวข้อคำขอ HTTP POST

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 '{
  "notification": {
    "title": "FCM Message",
    "body": "This is a Firebase Cloud Messaging Topic Message!",
  },
  "topic" : "foo-bar"
}' "https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1"

หัวข้อการตอบสนอง HTTP

{
    "name": "projects/myproject-b5ae1/messages/5735743068807585451"
}

หัวข้อข้อความ XMPP

ส่งไปที่หัวข้อเดียว:

 <message id="">
  <gcm xmlns="google:mobile:data">
{
  "to" : /topics/foo-bar",
  "priority" : "high",
  "notification" : {
    "body" : "This is a Firebase Cloud Messaging Topic Message!",
    "title" : "FCM Message",
  }
}
  </gcm>
</message>

หัวข้อการตอบสนอง XMPP

//Success example:
{
  "message_id": "1023456"
}

//failure example:
{
  "error": "TopicsMessageRateExceeded"
}