כדי לשלוח הודעה למספר מכשירים, צריך להשתמש בהודעות בנושאים. התכונה הזו מאפשרת לשלוח הודעה לכמה מכשירים שהמשתמשים בהם הצטרפו לנושא מסוים.
המדריך הזה מתמקד בשליחת הודעות לנושא משרת האפליקציה באמצעות 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, לוחצים על הוספת פרויקט.
-
כדי להוסיף משאבי Firebase לפרויקט קיים Google Cloud צריך להזין את שם הפרויקט או לבחור אותו מהתפריט הנפתח.
-
כדי ליצור פרויקט חדש, מזינים שם לפרויקט. אפשר גם לערוך את מזהה הפרויקט שמוצג מתחת לשם הפרויקט.
-
-
אם תופיע בקשה, תצטרכו לקרוא את התנאים של Firebase ולאשר אותם.
-
לוחצים על המשך.
-
(אופציונלי) מגדירים את Google Analytics לפרויקט, כדי ליהנות מחוויה אופטימלית באמצעות המוצרים הבאים של Firebase: Firebase A/B Testing, Cloud Messaging, Crashlytics, In-App Messaging ו-Remote Config (כולל התאמה אישית).
בוחרים חשבון Google Analytics קיים או יוצרים חשבון חדש. אם יוצרים חשבון חדש, בוחרים את Analytics מיקום הדיווח, ואז מאשרים את הגדרות שיתוף הנתונים ואת Google Analytics התנאים של הפרויקט.
-
לוחצים על יצירת פרויקט (או על הוספת Firebase, אם מוסיפים את Firebase לפרויקט קיים של Google Cloud).
מערכת Firebase מקצה באופן אוטומטי משאבים לפרויקט Firebase. בסיום התהליך, תועברו לדף הסקירה הכללית של פרויקט Firebase בFirebase מסוף.
רישום האפליקציה ב-Firebase
כדי להשתמש ב-Firebase באפליקציית Apple, צריך לרשום את האפליקציה בפרויקט Firebase. רישום האפליקציה נקרא לעיתים קרובות "הוספה" של האפליקציה לפרויקט.
עוברים אל מסוף Firebase.
במרכז הדף של סקירת הפרויקט, לוחצים על הסמל iOS+ כדי להפעיל את תהליך ההגדרה.
אם כבר הוספתם אפליקציה לפרויקט Firebase, לוחצים על הוספת אפליקציה כדי להציג את אפשרויות הפלטפורמה.
מזינים את מזהה החבילה של האפליקציה בשדה מזהה החבילה.
מה זה מזהה חבילה ואיפה הוא נמצא?
מזהה חבילה מזהה באופן ייחודי אפליקציה במערכת האקולוגית של אפל.
כדי למצוא את מזהה החבילה: פותחים את הפרויקט ב-Xcode, בוחרים את האפליקציה ברמה העליונה בסרגל הניווט של הפרויקט ואז בוחרים בכרטיסייה כללי.
הערך בשדה Bundle Identifier הוא מזהה החבילה (לדוגמה,
com.yourcompany.yourproject
).חשוב לדעת שהערך של מזהה החבילה הוא תלוי אותיות רישיות (case-sensitive), ואי אפשר לשנות אותו באפליקציית Firebase הזו אחרי שהיא נרשמת בפרויקט Firebase.
(אופציונלי) מזינים פרטים נוספים על האפליקציה: כינוי האפליקציה ומזהה האפליקציה בחנות.
איך משתמשים ב-Firebase בכינוי האפליקציה ובמזהה האפליקציה ב-App Store?
כינוי לאפליקציה: מזהה פנימי שנועד לנוחותכם ומוצג רק לכם במסוף Firebase
מזהה App Store: משמש את Firebase Dynamic Links כדי להפנות משתמשים לדף שלכם ב-App Store ואת Google Analytics כדי לייבא אירועי המרה אל Google Ads. אם לאפליקציה שלכם עדיין אין מזהה App Store, תוכלו להוסיף את המזהה מאוחר יותר בהגדרות הפרויקט.
לוחצים על רישום האפליקציה.
הוספת קובץ הגדרות של Firebase
לוחצים על Download GoogleService-Info.plist (הורדה של GoogleService-Info.plist) כדי לקבל את קובץ ההגדרות של אפליקציית Firebase (
GoogleService-Info.plist
).מה צריך לדעת על קובץ התצורה הזה?
קובץ התצורה של Firebase מכיל מזהים ייחודיים, אבל לא סודיים, של הפרויקט והאפליקציה. מידע נוסף על קובץ התצורה הזה זמין במאמר הסבר על פרויקטים ב-Firebase.
תמיד אפשר להוריד שוב את קובץ התצורה של Firebase.
מוודאים שלא נוספו תווים לשם של קובץ ההגדרות, כמו
(2)
.
מעבירים את קובץ ההגדרות לרמה הבסיסית (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:import SwiftUI import FirebaseCore import FirebaseFirestore import FirebaseAuth // ...
import FirebaseCore import FirebaseFirestore import FirebaseAuth // ...
@import FirebaseCore; @import FirebaseFirestore; @import FirebaseAuth; // ...
- מגדירים מופע משותף של
FirebaseApp
בשיטהapplication(_:didFinishLaunchingWithOptions:)
של נציג האפליקציה:// 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.@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 מנסה שוב באופן אוטומטי. במקרים שבהם אי אפשר להשלים את המינוי, המינוי מחזיר שגיאה שאפשר לטפל בה באמצעות handler להשלמה, כמו שמוצג כאן:
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); }
יצירת בקשות לשליחה
אחרי שיוצרים נושא, אפשר לשלוח אליו הודעות. אפשר ליצור נושא על ידי הרשמה של מופעים של אפליקציות לקוח לנושא בצד הלקוח או דרך ממשק ה-API של השרת. אם זו הפעם הראשונה שאתם יוצרים בקשות שליחה ל-FCM, כדאי לעיין במדריך בנושא סביבת השרת שלכם ו-FCM כדי לקבל מידע חשוב על הרקע וההגדרה.
בלוגיקה של השליחה בשרת העורפי, מציינים את שם הנושא הרצוי כמו שמוצג כאן:
// 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
אפשר לכלול עד חמישה נושאים בביטוי המותנה.
כדי לשלוח למישהו בתנאי:
// 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
השלבים הבאים
- אתם יכולים להשתמש בשרת כדי לרשום מופעים של אפליקציות לקוח לנושאים ולבצע משימות ניהול אחרות. איך מנהלים את המינויים לנושאים בשרת