כדי לשלוח הודעה למספר מכשירים, צריך להשתמש בהודעות בנושאים. התכונה הזו מאפשרת לשלוח הודעה לכמה מכשירים שהמשתמשים בהם הצטרפו לנושא מסוים.
המדריך הזה מתמקד בשליחת הודעות לנושא משרת האפליקציה באמצעות Admin SDK או REST API של FCM, וקבלתן וטיפול בהן באפליקציית אפל. בדף הזה מפורטים כל השלבים לביצוע הפעולות האלה, מההגדרה ועד האימות. יכול להיות שחלק מהשלבים כבר בוצעו אם הגדרתם אפליקציית לקוח של אפל ל-FCM או אם ביצעתם את השלבים לשליחת ההודעה הראשונה.
הוספת Firebase לפרויקט Apple
בקטע הזה מפורטות משימות שאולי כבר ביצעתם אם הפעלתם תכונות אחרות של Firebase באפליקציה. כדי להשתמש ב-FCM, תצטרכו להעלות את מפתח האימות של APNs ולהירשם לקבלת התראות מרחוק.
דרישות מוקדמות
מתקינים את הרכיבים הבאים:
- Xcode 16.2 ואילך
חשוב לוודא שהפרויקט עומד בדרישות הבאות:
- הפרויקט שלכם צריך להיות מיועד לגרסאות הפלטפורמה האלה ומעלה:
- iOS 13
- macOS 10.15
- tvOS 13
- watchOS 7
- הפרויקט שלכם צריך להיות מיועד לגרסאות הפלטפורמה האלה ומעלה:
מגדירים מכשיר Apple פיזי להרצת האפליקציה, ומבצעים את המשימות הבאות:
- משיגים מפתח אימות של Apple Push Notification בשביל חשבון Apple Developer.
- מפעילים את ההתראות בדחיפה ב-XCode בקטע App > Capabilities.
- נכנסים ל-Firebase באמצעות חשבון Google.
אם עדיין אין לכם פרויקט Xcode ואתם רק רוצים לנסות מוצר של Firebase, אתם יכולים להוריד אחת מדוגמאות ההפעלה המהירה שלנו.
יצירת פרויקט Firebase
לפני שמוסיפים את Firebase לאפליקציית Apple, צריך ליצור פרויקט Firebase כדי לקשר לאפליקציה. במאמר הסבר על פרויקטים ב-Firebase יש מידע נוסף על פרויקטים ב-Firebase.
רישום האפליקציה ב-Firebase
כדי להשתמש ב-Firebase באפליקציית Apple, צריך לרשום את האפליקציה בפרויקט Firebase. רישום האפליקציה נקרא לעיתים קרובות "הוספה" של האפליקציה לפרויקט.
עוברים אל מסוף Firebase.
במרכז הדף של סקירת הפרויקט, לוחצים על הסמל iOS+ כדי להפעיל את תהליך ההגדרה.
אם כבר הוספתם אפליקציה לפרויקט Firebase, לוחצים על הוספת אפליקציה כדי להציג את אפשרויות הפלטפורמה.
מזינים את מזהה החבילה של האפליקציה בשדה מזהה החבילה.
(אופציונלי) מזינים פרטים נוספים על האפליקציה: כינוי האפליקציה ומזהה האפליקציה בחנות.
לוחצים על רישום האפליקציה.
הוספת קובץ הגדרות של Firebase
לוחצים על Download GoogleService-Info.plist (הורדה של GoogleService-Info.plist) כדי לקבל את קובץ ההגדרות של אפליקציית Firebase (
GoogleService-Info.plist
).מעבירים את קובץ ההגדרות לרמה הבסיסית (root) של פרויקט Xcode. אם מוצגת בקשה, בוחרים להוסיף את קובץ ההגדרות לכל יעדי ההעברה.
אם יש לכם כמה מזהי חבילות בפרויקט, אתם צריכים לשייך כל מזהה חבילה לאפליקציה רשומה במסוף Firebase, כדי שלכל אפליקציה יהיה קובץ GoogleService-Info.plist
משלה.
הוספת ערכות SDK של Firebase לאפליקציה
משתמשים ב-Swift Package Manager כדי להתקין ולנהל יחסי תלות ב-Firebase.
- ב-Xcode, כשהפרויקט של האפליקציה פתוח, עוברים אל File > Add Packages (קובץ > הוספת חבילות).
- כשמוצגת בקשה, מוסיפים את מאגר Firebase Apple platforms SDK:
- בוחרים את הספרייה Firebase Cloud Messaging.
- מוסיפים את הדגל
-ObjC
לקטע Other Linker Flags בהגדרות הבנייה של היעד. - כדי ליהנות מחוויה אופטימלית עם Firebase Cloud Messaging, מומלץ להפעיל את Google Analytics בפרויקט Firebase ולהוסיף את Firebase SDK for Google Analytics לאפליקציה. אפשר לבחור בספרייה ללא איסוף של IDFA או עם איסוף של IDFA. אפשר לעיין בשאלות הנפוצות בנושא הארגון העדכני של מודולים ב-Google Analytics עבור Firebase SDK.
- אחרי שתסיימו, פלטפורמת Xcode תתחיל באופן אוטומטי לטפל ביחסי התלות ולהוריד אותם ברקע.
https://github.com/firebase/firebase-ios-sdk.git
העלאת מפתח אימות של APNs
מעלים את מפתח האימות של APNs ל-Firebase. אם עדיין אין לכם מפתח אימות של APNs, הקפידו ליצור אותו ב-Apple Developer Member Center.
-
בפרויקט במסוף Firebase, לוחצים על סמל גלגל השיניים, בוחרים באפשרות הגדרות הפרויקט ואז בוחרים בכרטיסייה Cloud Messaging.
-
בקטע הגדרת אפליקציה ל-iOS, בשדה מפתח אימות של APNs, לוחצים על לחצן העלאה.
-
מדפדפים למיקום שבו שמרתם את המפתח, בוחרים אותו ולוחצים על פתיחה. מוסיפים את מזהה המפתח (שזמין ב- 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
. צריך גם להשבית את החלפת השיטות של נציג האפליקציה. מידע נוסף זמין בהוראות ל-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
כמו שמוצג:
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 מנסה שוב באופן אוטומטי. במקרים שבהם אי אפשר להשלים את המינוי, המינוי מחזיר שגיאה שאפשר לטפל בה באמצעות handler להשלמה, כמו שמוצג כאן:
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
כדי לשלוח הודעה לשילוב של נושאים, צריך לציין תנאי, שהוא ביטוי בוליאני שמציין את נושאי היעד. לדוגמה, התנאי הבא ישלח הודעות למכשירים שמנויים ל-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);
});
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
השלבים הבאים
- אתם יכולים להשתמש בשרת כדי לרשום מופעים של אפליקציות לקוח לנושאים ולבצע משימות ניהול אחרות. איך מנהלים את המינויים לנושאים בשרת