يوفر Firebase Cloud Messaging طريقتين لتوجيه رسالة إلى أجهزة متعددة:
- رسائل الموضوع ، والتي تتيح لك إرسال رسالة إلى العديد من الأجهزة التي اشتركت في موضوع معين.
- مراسلة مجموعة الأجهزة ، والتي تتيح لك إرسال رسالة واحدة إلى مثيلات متعددة لتطبيق يعمل على أجهزة تنتمي إلى مجموعة.
يركز هذا البرنامج التعليمي على إرسال رسائل الموضوع من خادم التطبيق الخاص بك باستخدام Admin SDK أو REST API for FCM ، واستلامها ومعالجتها في تطبيق Apple. تسرد هذه الصفحة جميع الخطوات لتحقيق ذلك ، من الإعداد إلى التحقق - لذلك قد تغطي الخطوات التي أكملتها بالفعل إذا قمت بإعداد تطبيق عميل Apple لـ FCM أو عملت من خلال الخطوات لإرسال رسالتك الأولى .
أضف Firebase إلى مشروع Apple الخاص بك
يغطي هذا القسم المهام التي ربما تكون قد أكملتها إذا كنت قد قمت بالفعل بتمكين ميزات Firebase الأخرى لتطبيقك. بالنسبة إلى FCM على وجه التحديد ، ستحتاج إلى تحميل مفتاح مصادقة APN الخاص بك والتسجيل في الإشعارات عن بُعد .
المتطلبات الأساسية
قم بتثبيت ما يلي:
- Xcode 13.3.1 أو أحدث
تأكد من أن مشروعك يلبي هذه المتطلبات:
- يجب أن يستهدف مشروعك إصدارات النظام الأساسي هذه أو أحدث:
- iOS 11
- macOS 10.13
- tvOS 12
- watchOS 6
- يجب أن يستهدف مشروعك إصدارات النظام الأساسي هذه أو أحدث:
قم بإعداد جهاز Apple فعليًا لتشغيل تطبيقك ، وأكمل هذه المهام:
- احصل على مفتاح مصادقة Apple Push Notification لحساب Apple Developer الخاص بك.
- قم بتمكين دفع الإخطارات في XCode ضمن التطبيق> القدرات .
- سجّل الدخول إلى Firebase باستخدام حساب Google الخاص بك.
إذا لم يكن لديك بالفعل مشروع Xcode وترغب فقط في تجربة أحد منتجات Firebase ، فيمكنك تنزيل إحدى عينات البدء السريع الخاصة بنا.
أنشئ مشروع Firebase
قبل أن تتمكن من إضافة Firebase إلى تطبيق Apple الخاص بك ، تحتاج إلى إنشاء مشروع Firebase للاتصال بتطبيقك. تفضل بزيارة فهم مشاريع Firebase لمعرفة المزيد حول مشاريع Firebase.
سجّل تطبيقك في Firebase
لاستخدام Firebase في تطبيق Apple ، يلزمك تسجيل تطبيقك في مشروع Firebase. غالبًا ما يسمى تسجيل تطبيقك "إضافة" تطبيقك إلى مشروعك.
انتقل إلى وحدة تحكم Firebase .
في وسط صفحة نظرة عامة على المشروع ، انقر فوق أيقونة + iOS لبدء سير عمل الإعداد.
إذا كنت قد أضفت بالفعل تطبيقًا إلى مشروع Firebase ، فانقر فوق إضافة تطبيق لعرض خيارات النظام الأساسي.
أدخل معرف حزمة التطبيق الخاص بك في حقل معرف الحزمة .
يحدد معرف الحزمة بشكل فريد تطبيقًا في نظام Apple البيئي.
ابحث عن معرف الحزمة الخاص بك: افتح مشروعك في Xcode ، وحدد التطبيق ذي المستوى الأعلى في متصفح المشروع ، ثم حدد علامة التبويب " عام ".
قيمة حقل معرف الحزمة هي معرف الحزمة (على سبيل المثال ،
com.yourcompany.yourproject
).اعلم أن قيمة معرّف الحزمة حساسة لحالة الأحرف ، ولا يمكن تغييرها لتطبيق Firebase هذا بعد تسجيله في مشروع Firebase.
(اختياري) أدخل معلومات التطبيق الأخرى: لقب التطبيق ومعرف متجر التطبيقات .
لقب التطبيق : معرّف داخلي ملائم يكون مرئيًا لك فقط في وحدة تحكم Firebase
معرف متجر التطبيقات : تستخدمه روابط Firebase الديناميكية لإعادة توجيه المستخدمين إلى صفحة App Store الخاصة بك ومن خلال Google Analytics لاستيراد أحداث التحويل إلى إعلانات Google . إذا لم يكن لتطبيقك معرّف متجر التطبيقات حتى الآن ، يمكنك إضافة المعرّف لاحقًا في إعدادات المشروع .
انقر فوق تسجيل التطبيق .
أضف ملف تهيئة Firebase
انقر فوق تنزيل GoogleService-Info.plist للحصول على ملف تهيئة أنظمة تشغيل Firebase Apple (
GoogleService-Info.plist
).يحتوي ملف تهيئة Firebase على معرّفات فريدة ولكنها غير سرية لمشروعك. لمعرفة المزيد حول ملف التكوين هذا ، تفضل بزيارة فهم مشاريع Firebase .
يمكنك تنزيل ملف تهيئة Firebase مرة أخرى في أي وقت.
تأكد من عدم إلحاق اسم ملف التكوين بأحرف إضافية ، مثل
(2)
.
انقل ملف التكوين الخاص بك إلى جذر مشروع Xcode الخاص بك. إذا طُلب منك ذلك ، فحدد لإضافة ملف التكوين إلى جميع الأهداف.
إذا كان لديك عدة معرّفات حزمة في مشروعك ، فيجب عليك إقران كل معرّف حزمة بتطبيق مسجل في وحدة تحكم Firebase بحيث يمكن أن يكون لكل تطبيق ملف GoogleService-Info.plist
الخاص به.
أضف حزم Firebase SDK إلى تطبيقك
استخدم Swift Package Manager لتثبيت وإدارة تبعيات Firebase.
- في Xcode ، مع فتح مشروع التطبيق الخاص بك ، انتقل إلى ملف> إضافة حزم .
- عند المطالبة ، أضف مستودع SDK لأنظمة Apple الأساسية لـ Firebase:
- اختر مكتبة Firebase Cloud Messaging.
- للحصول على تجربة مثالية مع Firebase Cloud Messaging ، نوصي بتمكين Google Analytics في مشروع Firebase وإضافة Firebase SDK لـ Google Analytics إلى تطبيقك. يمكنك تحديد المكتبة بدون مجموعة IDFA أو مع مجموعة IDFA.
- عند الانتهاء ، سيبدأ Xcode تلقائيًا في حل وتنزيل التبعيات الخاصة بك في الخلفية.
https://github.com/firebase/firebase-ios-sdk
قم بتحميل مفتاح مصادقة APNs الخاص بك
قم بتحميل مفتاح مصادقة APNs الخاص بك إلى Firebase. إذا لم يكن لديك بالفعل مفتاح مصادقة APNs ، فتأكد من إنشاء واحد في مركز أعضاء مطوري Apple .
داخل مشروعك في وحدة تحكم Firebase ، حدد رمز الترس ، وحدد إعدادات المشروع ، ثم حدد علامة التبويب Cloud Messaging .
في مفتاح مصادقة APN ضمن تكوين تطبيق iOS ، انقر فوق الزر تحميل .
استعرض للوصول إلى الموقع الذي قمت فيه بحفظ مفتاحك ، وحدده ، وانقر فوق فتح . أضف معرف المفتاح للمفتاح (متوفر في مركز أعضاء مطوري Apple ) وانقر فوق تحميل .
ابدأ تشغيل Firebase في تطبيقك
ستحتاج إلى إضافة رمز تهيئة Firebase إلى تطبيقك. قم باستيراد وحدة Firebase وتهيئة مثيل مشترك كما هو موضح:
- قم باستيراد وحدة
FirebaseCore
في مندوبUIApplicationDelegate
، بالإضافة إلى أي وحدات Firebase أخرى يستخدمها مفوض التطبيق. على سبيل المثال ، لاستخدام Cloud Firestore والمصادقة:SwiftUI
import SwiftUI import FirebaseCore import FirebaseFirestore import FirebaseAuth // ...
سويفت
import FirebaseCore import FirebaseFirestore import FirebaseAuth // ...
ج موضوعية
@import FirebaseCore; @import FirebaseFirestore; @import FirebaseAuth; // ...
- قم بتهيئة مثيل
FirebaseApp
مشترك في تطبيق مفوضapplication(_:didFinishLaunchingWithOptions:)
:SwiftUI
// Use Firebase library to configure APIs FirebaseApp.configure()
سويفت
// Use Firebase library to configure APIs FirebaseApp.configure()
ج موضوعية
// Use Firebase library to configure APIs [FIRApp configure];
- إذا كنت تستخدم SwiftUI ، فيجب عليك إنشاء مفوض للتطبيق وإرفاقه بهيكل
App
الخاص بك عبرUIApplicationDelegateAdaptor
أوNSApplicationDelegateAdaptor
. يجب عليك أيضًا تعطيل استخدام مفوض التطبيق. لمزيد من المعلومات ، راجع تعليمات SwiftUI .SwiftUI
@main struct YourApp: App { // register app delegate for Firebase setup @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate var body: some Scene { WindowGroup { NavigationView { ContentView() } } } }
التسجيل للحصول على الإخطارات عن بعد
سواء عند بدء التشغيل ، أو في النقطة المطلوبة في تدفق التطبيق الخاص بك ، قم بتسجيل التطبيق الخاص بك للإشعارات عن بعد. سجل المكالماتregisterForRemoteNotifications
كما هو موضح:سويفت
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];
اشترك في تطبيق العميل في موضوع
يمكن لتطبيقات العميل الاشتراك في أي موضوع موجود ، أو يمكنهم إنشاء موضوع جديد. عندما يشترك تطبيق عميل في اسم موضوع جديد (اسم غير موجود بالفعل لمشروع 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 لإلغاء الاشتراك من الموضوع في الخلفية.
تلقي رسائل الموضوع والتعامل معها
يقوم 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
الخطوات التالية
- يمكنك استخدام الخادم الخاص بك للاشتراك في طبعات تطبيق العميل في الموضوعات وتنفيذ مهام الإدارة الأخرى. راجع إدارة اشتراكات الموضوع على الخادم .
- تعرف على المزيد حول الطريقة الأخرى للإرسال إلى أجهزة متعددة - رسائل مجموعة الأجهزة