שלח הודעות למספר מכשירים בפלטפורמות של אפל

Firebase Cloud Messaging מספקת שתי דרכים למקד הודעה למספר מכשירים:

  • הודעות נושא , המאפשרות לשלוח הודעה למספר מכשירים שהצטרפו לנושא מסוים.
  • הודעות קבוצתיות במכשיר , המאפשרת לשלוח הודעה בודדת למספר מופעים של אפליקציה הפועלת במכשירים השייכים לקבוצה.

מדריך זה מתמקד בשליחת הודעות נושא משרת האפליקציות שלך באמצעות ה- Admin SDK או REST API עבור FCM, וקבלה וטיפול בהן באפליקציית Apple. דף זה מפרט את כל השלבים להשגת זאת, מההגדרה ועד לאימות - כך שהוא עשוי לכסות את השלבים שכבר השלמת אם הגדרת אפליקציית לקוח של Apple עבור FCM או עברת את השלבים לשליחת ההודעה הראשונה שלך .

הוסף את Firebase לפרויקט Apple שלך

חלק זה מכסה משימות שייתכן שהשלמת אם כבר הפעלת תכונות אחרות של Firebase עבור האפליקציה שלך. עבור FCM ספציפית, תצטרך להעלות את מפתח האימות של ה-APN שלך ולהירשם לקבלת התראות מרחוק .

דרישות מוקדמות

  • התקן את הדברים הבאים:

    • Xcode 13.3.1 ואילך
  • ודא שהפרויקט שלך עומד בדרישות הבאות:

    • הפרויקט שלך חייב למקד לגרסאות הפלטפורמה האלה או מאוחרות יותר:
      • iOS 10
      • macOS 10.12
      • tvOS 12
      • watchOS 6
  • הגדר מכשיר אפל פיזי להפעלת האפליקציה שלך והשלם את המשימות הבאות:

    • השג מפתח אימות של Apple Push Notification עבור חשבון ה-Apple Developer שלך.
    • אפשר הודעות דחיפה ב-XCode תחת אפליקציה > יכולות .

אם עדיין אין לך פרויקט Xcode ואתה רק רוצה לנסות מוצר Firebase, אתה יכול להוריד את אחת מדוגמאות ההתחלה המהירה שלנו.

צור פרויקט Firebase

לפני שתוכל להוסיף את Firebase לאפליקציית Apple שלך, עליך ליצור פרויקט Firebase כדי להתחבר לאפליקציה שלך. בקר בהבנת פרויקטים של Firebase כדי ללמוד עוד על פרויקטים של Firebase.

רשום את האפליקציה שלך ב-Firebase

כדי להשתמש ב-Firebase באפליקציית Apple שלך, עליך לרשום את האפליקציה שלך בפרויקט Firebase שלך. רישום האפליקציה שלך נקרא לעתים קרובות "הוספת" האפליקציה שלך לפרויקט שלך.

  1. עבור אל מסוף Firebase .

  2. במרכז דף סקירת הפרויקט, לחץ על סמל iOS+ כדי להפעיל את זרימת העבודה של ההגדרה.

    אם כבר הוספת אפליקציה לפרויקט Firebase שלך, לחץ על הוסף אפליקציה כדי להציג את אפשרויות הפלטפורמה.

  3. הזן את מזהה החבילה של האפליקציה שלך בשדה מזהה החבילה .

  4. (אופציונלי) הזן מידע אחר על האפליקציה: כינוי לאפליקציה ומזהה App Store .

  5. לחץ על הרשמה אפליקציה .

הוסף קובץ תצורה של Firebase

  1. לחץ על הורד את GoogleService-Info.plist כדי להשיג את קובץ התצורה של Firebase Apple platforms שלך ( GoogleService-Info.plist ).

  2. העבר את קובץ התצורה שלך לשורש פרויקט ה-Xcode שלך. אם תתבקש, בחר להוסיף את קובץ התצורה לכל היעדים.

אם יש לך מספר מזהי חבילה בפרויקט שלך, עליך לשייך כל מזהה חבילה לאפליקציה רשומה במסוף Firebase כך שלכל אפליקציה תהיה קובץ GoogleService-Info.plist .

הוסף ערכות פיתוח של Firebase לאפליקציה שלך

השתמש ב- Swift Package Manager כדי להתקין ולנהל תלות ב-Firebase.

  1. ב-Xcode, כשפרויקט האפליקציה שלך פתוח, נווט אל קובץ > הוסף חבילות .
  2. כשתתבקש, הוסף את מאגר Firebase Apple platforms SDK:
  3.   https://github.com/firebase/firebase-ios-sdk
  4. בחר את ספריית Firebase Cloud Messaging.
  5. לחוויה אופטימלית עם Firebase Cloud Messaging, אנו ממליצים להפעיל את Google Analytics בפרויקט Firebase שלך ​​ולהוסיף את Firebase SDK עבור Google Analytics לאפליקציה שלך. אתה יכול לבחור בספרייה ללא אוסף IDFA או עם אוסף IDFA.
  6. בסיום, Xcode יתחיל באופן אוטומטי לפתור ולהוריד את התלות שלך ברקע.

העלה את מפתח האימות של ה-APN שלך

העלה את מפתח האימות של ה-APN שלך ל-Firebase. אם עדיין אין לך מפתח אימות APNs, הקפד ליצור אחד ב- Apple Developer Member Center .

  1. בתוך הפרויקט שלך במסוף Firebase, בחר בסמל גלגל השיניים, בחר הגדרות פרויקט ולאחר מכן בחר בכרטיסייה הודעות ענן .

  2. במפתח אימות APN תחת תצורת אפליקציית iOS , לחץ על כפתור העלה .

  3. דפדף למיקום שבו שמרת את המפתח שלך, בחר אותו ולחץ על פתח . הוסף את מזהה המפתח של המפתח (זמין ב- Apple Developer Member Center ) ולחץ על העלה .

אתחל את Firebase באפליקציה שלך

יהיה עליך להוסיף קוד אתחול Firebase לאפליקציה שלך. ייבא את מודול Firebase והגדר מופע משותף כפי שמוצג:

  1. ייבא את מודול FirebaseCore ב- UIApplicationDelegate שלך, כמו גם כל מודולי Firebase אחרים שנציג האפליקציה שלך משתמש בו. לדוגמה, כדי להשתמש ב-Cloud Firestore ובאימות:

    מָהִיר

    import FirebaseCore
    import FirebaseFirestore
    import FirebaseAuth
    // ...
          

    Objective-C

    @import FirebaseCore;
    @import FirebaseFirestore;
    @import FirebaseAuth;
    // ...
          
  2. הגדר מופע משותף של FirebaseApp , בדרך כלל בשיטת האתחול של App או בשיטת application(_:didFinishLaunchingWithOptions:) של האפליקציה שלך:

    מָהִיר

    // Use Firebase library to configure APIs
    FirebaseApp.configure()

    Objective-C

    // Use Firebase library to configure APIs
    [FIRApp configure];

הירשם לקבלת התראות מרחוק

או בעת ההפעלה, או בנקודה הרצויה בזרימת היישום שלך, רשום את האפליקציה שלך לקבלת התראות מרחוק. Call registerForRemoteNotifications כפי שמוצג:

מָהִיר

if #available(iOS 10.0, *) {
  // For iOS 10 display notification (sent via APNS)
  UNUserNotificationCenter.current().delegate = self

  let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
  UNUserNotificationCenter.current().requestAuthorization(
    options: authOptions,
    completionHandler: { _, _ in }
  )
} else {
  let settings: UIUserNotificationSettings =
    UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
  application.registerUserNotificationSettings(settings)
}

application.registerForRemoteNotifications()

Objective-C

if ([UNUserNotificationCenter class] != nil) {
  // iOS 10 or later
  // For iOS 10 display notification (sent via APNS)
  [UNUserNotificationCenter currentNotificationCenter].delegate = self;
  UNAuthorizationOptions authOptions = UNAuthorizationOptionAlert |
      UNAuthorizationOptionSound | UNAuthorizationOptionBadge;
  [[UNUserNotificationCenter currentNotificationCenter]
      requestAuthorizationWithOptions:authOptions
      completionHandler:^(BOOL granted, NSError * _Nullable error) {
        // ...
      }];
} else {
  // iOS 10 notifications aren't available; fall back to iOS 8-9 notifications.
  UIUserNotificationType allNotificationTypes =
  (UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge);
  UIUserNotificationSettings *settings =
  [UIUserNotificationSettings settingsForTypes:allNotificationTypes categories:nil];
  [application registerUserNotificationSettings:settings];
}

[application registerForRemoteNotifications];

הירשם לאפליקציית הלקוח לנושא

אפליקציות לקוח יכולות להירשם לכל נושא קיים, או שהן יכולות ליצור נושא חדש. כאשר אפליקציית לקוח נרשמת לשם נושא חדש (כזה שלא קיים כבר עבור פרויקט Firebase שלך), נושא חדש בשם זה נוצר ב-FCM וכל לקוח יכול להירשם אליו לאחר מכן.

כדי להירשם לנושא, התקשר לשיטת המנוי מהשרשור הראשי של היישום שלך (FCM אינו בטוח לשרשור). אם בקשת המנוי נכשלת בתחילה, FCM מנסה שוב באופן אוטומטי. במקרים שבהם לא ניתן להשלים את המנוי, המנוי זורק שגיאה שתוכל לתפוס במטפל השלמה כפי שמוצג:

מָהִיר

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 , ודא שמופע אפליקציית הלקוח כבר קיבל אסימון רישום דרך ה-callback 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
}

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);

פִּיתוֹן

# 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)

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);

מנוחה

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);

פִּיתוֹן

# 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)

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);

מנוחה

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

הצעדים הבאים