Catch up on everthing we announced at this year's Firebase Summit. Learn more

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

בהתבסס על מודל הפרסום/הרשמה, הודעות בנושא 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")
}

Objective-C

[[FIRMessaging messaging] subscribeToTopic:@"weather"
                                completion:^(NSError * _Nullable error) {
  NSLog(@"Subscribed to weather topic");
}];

שיחה זו מבקשת בקשה א -סינכרונית למערך האחורי של ה- FCM ומרשמת את הלקוח לנושא הנתון. לפני קריאה subscribeToTopic:topic , לוודא כי מופע יישום הלקוח כבר קיבל רישום האסימון באמצעות התקשרות didReceiveRegistrationToken .

בכל פעם שהאפליקציה מתחילה, FCM מוודאת כי כל הנושאים המבוקשים נרשמו כמנוי. כדי לבטל את המנוי, קוראים unsubscribeFromTopic:topic , וביטלו רישום FCM מהנושא ברקע.

נהל מנויי נושאים בשרת

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

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

תוכל להעביר רשימה של אסימוני רישום לשיטת המנוי ל- SDK Admin Firebase Admin כדי להירשם כמכשירים המתאימים לנושא:

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

C#

// 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")

C#

// 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. לסוג ההחזרה יש אותו פורמט ללא קשר למספר אסימוני הרישום שצוין בבקשה.

במקרה של שגיאה (כשלים באימות, אסימון לא חוקי או נושא וכו ') שיטות אלה גורמות לשגיאה. לקבלת רשימה מלאה של קודי שגיאה, כולל תיאורים צעדים רזולוציה, לראות שגיאות API FCM Admin .

קבלת הודעות נושא וטיפול בהן

FCM מעבירה הודעות בנושא באותו אופן כמו הודעות אחרות במורד הזרם.

ליישם application(_:didReceiveRemoteNotification:fetchCompletionHandler:) כמוצג:

מָהִיר

func application(_ application: UIApplication,
                 didReceiveRemoteNotification userInfo: [AnyHashable: Any],
                 fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult)
                   -> Void) {
  // 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)

  completionHandler(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);
  });

ג'אווה

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

ג'אווה

// 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

הצעדים הבאים