استنادًا إلى نموذج النشر / الاشتراك ، تتيح لك رسائل موضوع FCM إرسال رسالة إلى أجهزة متعددة اشتركت في موضوع معين. تقوم بإنشاء رسائل الموضوع حسب الحاجة ، ويتولى FCM توجيه الرسائل وتسليمها بشكل موثوق إلى الأجهزة المناسبة.
على سبيل المثال ، يمكن لمستخدمي تطبيق التنبؤ بالمد والجزر المحلي الاشتراك في موضوع "تنبيهات التيارات المد والجزر" وتلقي إشعارات بالظروف المثلى لصيد الأسماك في المياه المالحة في مناطق محددة. يمكن لمستخدمي تطبيق رياضي الاشتراك في التحديثات التلقائية في نتائج المباريات المباشرة لفرقهم المفضلة.
بعض الأشياء التي يجب وضعها في الاعتبار حول الموضوعات:
- تعد رسائل الموضوع هي الأنسب لمحتوى مثل الطقس أو غيرها من المعلومات المتاحة للجمهور.
- تم تحسين رسائل الموضوع للإنتاجية بدلاً من وقت الاستجابة . للتسليم السريع والآمن لأجهزة فردية أو مجموعات صغيرة من الأجهزة ، استهدف الرسائل إلى رموز التسجيل ، وليس الموضوعات.
- إذا كنت بحاجة إلى إرسال رسائل إلى أجهزة متعددة لكل مستخدم ، ففكر في مراسلة مجموعة الأجهزة لحالات الاستخدام هذه.
- تدعم رسائل الموضوع اشتراكات غير محدودة لكل موضوع. ومع ذلك ، تفرض FCM قيودًا في هذه المجالات:
- يمكن الاشتراك في مثيل واحد للتطبيق في ما لا يزيد عن 2000 موضوع.
- إذا كنت تستخدم استيراد دُفعات للاشتراك في نسخ التطبيق ، فسيقتصر كل طلب على 1000 نسخة تطبيق.
- تواتر الاشتراكات الجديدة محدود السعر لكل مشروع. إذا أرسلت عددًا كبيرًا جدًا من طلبات الاشتراك في فترة زمنية قصيرة ، فستستجيب خوادم FCM باستجابة
429 RESOURCE_EXHAUSTED
("تجاوز الحصة"). أعد المحاولة مع التراجع الأسي.
اشترك في تطبيق العميل في موضوع
يمكن لتطبيقات العميل الاشتراك في أي موضوع موجود ، أو يمكنهم إنشاء موضوع جديد. عندما يشترك تطبيق عميل في اسم موضوع جديد (اسم غير موجود بالفعل لمشروع Firebase الخاص بك) ، يتم إنشاء موضوع جديد بهذا الاسم في FCM ويمكن لأي عميل الاشتراك فيه لاحقًا.
للاشتراك في موضوع ما ، قم باستدعاء طريقة الاشتراك من سلسلة المحادثات الرئيسية للتطبيق الخاص بك (FCM ليس آمنًا على مؤشر الترابط). إذا فشل طلب الاشتراك في البداية ، تقوم FCM بإعادة المحاولة تلقائيًا. بالنسبة للحالات التي لا يمكن فيها إكمال الاشتراك ، يلقي الاشتراك خطأ يمكنك اكتشافه في معالج الإكمال كما هو موضح:
سويفت
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"); }];
يقوم هذا الاستدعاء بإجراء طلب غير متزامن إلى الواجهة الخلفية FCM ويشترك العميل في الموضوع المحدد. قبل استدعاء subscribeToTopic:topic
، تأكد من أن مثيل تطبيق العميل قد تلقى بالفعل رمزًا مميزًا للتسجيل عبر رد الاتصال didReceiveRegistrationToken
.
في كل مرة يبدأ فيها التطبيق ، تتأكد FCM من أن جميع الموضوعات المطلوبة قد تم الاشتراك فيها. لإلغاء الاشتراك ، اتصل بـ unsubscribeFromTopic:topic
، و FCM لإلغاء الاشتراك من الموضوع في الخلفية.
إدارة اشتراكات الموضوع على الخادم
تسمح لك حزمة Firebase Admin SDK بأداء مهام إدارة الموضوع الأساسية من جانب الخادم. نظرًا لرمز (رموز) التسجيل الخاصة بهم ، يمكنك الاشتراك وإلغاء الاشتراك في طبعات تطبيق العميل بشكل مجمّع باستخدام منطق الخادم.
يمكنك الاشتراك في طبعات تطبيق العميل في أي موضوع موجود ، أو يمكنك إنشاء موضوع جديد. عند استخدام واجهة برمجة التطبيقات للاشتراك في تطبيق عميل في موضوع جديد (موضوع غير موجود بالفعل لمشروع Firebase الخاص بك) ، يتم إنشاء موضوع جديد بهذا الاسم في FCM ويمكن لأي عميل الاشتراك فيه لاحقًا.
يمكنك تمرير قائمة من الرموز المميزة للتسجيل إلى طريقة اشتراك Firebase Admin SDK للاشتراك في الأجهزة المقابلة في أحد الموضوعات:
Node.js
// These registration tokens come from the client FCM SDKs.
const registrationTokens = [
'YOUR_REGISTRATION_TOKEN_1',
// ...
'YOUR_REGISTRATION_TOKEN_n'
];
// Subscribe the devices corresponding to the registration tokens to the
// topic.
getMessaging().subscribeToTopic(registrationTokens, topic)
.then((response) => {
// See the MessagingTopicManagementResponse reference documentation
// for the contents of response.
console.log('Successfully subscribed to topic:', response);
})
.catch((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.
const registrationTokens = [
'YOUR_REGISTRATION_TOKEN_1',
// ...
'YOUR_REGISTRATION_TOKEN_n'
];
// Unsubscribe the devices corresponding to the registration tokens from
// the topic.
getMessaging().unsubscribeFromTopic(registrationTokens, topic)
.then((response) => {
// See the MessagingTopicManagementResponse reference documentation
// for the contents of response.
console.log('Successfully unsubscribed from topic:', response);
})
.catch((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 .
تلقي رسائل الموضوع والتعامل معها
يقوم 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 }
ج موضوعية
- (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); }
بناء إرسال الطلبات
بعد إنشاء موضوع ، إما عن طريق الاشتراك في طبعات تطبيق العميل في الموضوع من جانب العميل أو عبر واجهة برمجة تطبيقات الخادم ، يمكنك إرسال رسائل إلى الموضوع. إذا كانت هذه هي المرة الأولى التي تقوم فيها بالبناء ، فأرسل طلبات لـ 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);
});
جافا
// 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:
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
يمكنك تضمين ما يصل إلى خمسة مواضيع في تعبيرك الشرطي.
للإرسال إلى شرط:
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);
});
جافا
// 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:
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
الخطوات التالية
- تعرف على المزيد حول الطريقة الأخرى للإرسال إلى أجهزة متعددة - رسائل مجموعة الأجهزة