Apple platformlarındaki konulara mesaj gönderme

Yayınlama/abone olma modeline dayalı olan FCM konu mesajlaşma özelliği, belirli bir konuyu etkinleştiren birden fazla cihaza mesaj göndermenize olanak tanır. Gerekli olduğu şekilde konu mesajları oluşturursunuz ve FCM, mesajın doğru cihazlara güvenilir bir şekilde yönlendirilmesini ve teslim edilmesini sağlar.

Örneğin, yerel bir gelgit tahmini uygulamasının kullanıcıları "gelgit akıntıları uyarıları" konusunu etkinleştirerek belirli bölgelerde tuzlu su balıkçılığı için en uygun koşulların bildirimlerini alabilir. Bir spor uygulaması kullanıcıları, tuttukları takımların canlı maç skorlarıyla ilgili otomatik güncellemelere abone olabilir.

Konularla ilgili olarak göz önünde bulundurulması gereken bazı noktalar:

  • Konu mesajlaşması, hava durumu gibi içerikler veya herkese açık diğer bilgiler için en uygun yöntemdir.
  • Konu mesajları gecikme yerine işleme hızı için optimize edilir. Tek cihazlara veya küçük cihaz gruplarına hızlı ve güvenli teslimat için mesajları konulara değil, kayıt jetonlarına hedefleyin.
  • Kullanıcı başına birden fazla cihaza mesaj göndermeniz gerekiyorsa bu kullanım alanları için cihaz grubu mesajlaşmasını kullanabilirsiniz.
  • Konu mesajlaşma, her konu için sınırsız aboneliği destekler. Ancak FCM şu alanlarda sınırları zorunlu kılar:
    • Bir uygulama örneği en fazla 2.000 konuya abone olabilir.
    • Uygulama örneklerine abone olmak için toplu içe aktarma özelliğini kullanıyorsanız her istek 1.000 uygulama örneğiyle sınırlıdır.
    • Yeni aboneliklerin sıklığı proje başına hız sınırlamasına tabidir. Kısa süre içinde çok fazla abonelik isteği gönderirseniz FCM sunucuları 429 RESOURCE_EXHAUSTED ("kota aşıldı") yanıtını verir. Eksponansiyel geri yüklemeyle yeniden deneyin.

İstemci uygulamasını bir konuya abone etme

İstemci uygulamaları, mevcut herhangi bir konuya abone olabilir veya yeni bir konu oluşturabilir. Bir istemci uygulaması yeni bir konu adına (Firebase projenizde henüz mevcut olmayan bir ad) abone olduğunda FCM içinde bu ada sahip yeni bir konu oluşturulur ve daha sonra herhangi bir istemci bu konuya abone olabilir.

Bir konuya abone olmak için uygulamanızın ana iş parçacığından abonelik yöntemini çağırın (FCM iş parçacığı açısından güvenli değildir). Abonelik isteği ilk başta başarısız olursa FCM otomatik olarak yeniden denenir. Aboneliğin tamamlanamadığı durumlarda, abonelik, tamamlanma işleyicisinde yakalayabileceğiniz bir hata verir.

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");
}];

Bu çağrı, FCM arka uca eşzamansız bir istekte bulunur ve istemciyi belirtilen konuya abone eder. subscribeToTopic:topic işlevini çağırmadan önce istemci uygulaması örneğinin, geri çağırma didReceiveRegistrationToken aracılığıyla bir kayıt jetonu aldığından emin olun.

Uygulama her başlatıldığında FCM, istenen tüm konulara abone olunduğundan emin olur. Abonelikten çıkmak için unsubscribeFromTopic:topic numaralı telefonu arayın. FCM, arka planda konu aboneliğinden çıkar.

Sunucudaki konu aboneliklerini yönetme

Firebase Admin SDK sunucu tarafında temel konu yönetimi görevlerini gerçekleştirmenize olanak tanır. Kayıt jetonları verildiğinde, sunucu mantığını kullanarak istemci uygulaması örneklerine toplu olarak abone olabilir ve abonelikten çıkabilirsiniz.

İstemci uygulaması örneklerini mevcut herhangi bir konuya abone edebilir veya yeni bir konu oluşturabilirsiniz. Bir istemci uygulamasını yeni bir konuya (Firebase projenizde henüz mevcut olmayan bir konu) abone etmek için API'yi kullandığınızda FCM'de bu adla yeni bir konu oluşturulur ve daha sonra herhangi bir istemci bu konuya abone olabilir.

İlgili cihazları bir konuya abone etmek için Firebase Admin SDK abonelik yöntemine kayıt jetonlarının bir listesini iletebilirsiniz:

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

Java

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

Python

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

Go

// 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");
Firebase Admin SDK'yı sunucunuza ekleme başlıklı makaledeki adımları uygulamanız gerekir.

Yönetici FCM API'si, kayıt jetonlarını uygun yönteme ileterek cihazların bir konunun e-posta listesinden çıkmasına da olanak tanır:

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

Java

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

Python

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

Go

// 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() ve unsubscribeFromTopic() yöntemleri, FCM'dan gelen yanıtı içeren bir nesneyle sonuçlanır. Dönüş türü, istekte belirtilen kayıt jetonlarının sayısından bağımsız olarak aynı biçime sahiptir.

Hata durumunda (kimlik doğrulama hataları, geçersiz jeton veya konu vb.) bu yöntemler hataya neden olur. Açıklamalar ve çözüm adımları da dahil olmak üzere hata kodlarının tam listesi için Admin FCM API Hataları başlıklı makaleyi inceleyin.

Konu mesajlarını alma ve işleme

FCM, konu iletilerini diğer aşağı akış iletileriyle aynı şekilde dağıtır.

application(_:didReceiveRemoteNotification:fetchCompletionHandler:) işaretlemesini gösterildiği gibi uygulayın:

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

Gönderme istekleri oluşturma

Bir konuyu istemci tarafında istemci uygulaması örneklerini konuya abone ederek veya sunucu API'si aracılığıyla oluşturduktan sonra konuya mesaj gönderebilirsiniz. FCM için ilk kez gönderme isteği oluşturuyorsanız önemli arka plan ve kurulum bilgileri için sunucu ortamınız ve FCM ile ilgili kılavuza bakın.

Arka uçtaki gönderme mantığınızda, istediğiniz konu adını aşağıdaki gibi belirtin:

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 komutu:

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

Bir konu kombinasyonuna mesaj göndermek için hedef konuları belirten bir Boole ifadesi olan koşul belirtin. Örneğin, aşağıdaki koşul, mesajları TopicA'ya abone olan ve TopicB veya TopicC cihazlarına gönderir:

"'TopicA' in topics && ('TopicB' in topics || 'TopicC' in topics)"

FCM önce parantez içindeki koşulları değerlendirir, ardından ifadeyi soldan sağa doğru değerlendirir. Yukarıdaki ifadede, herhangi bir konuya abone olan kullanıcı mesajı almaz. Aynı şekilde, TopicA kanalına abone olmayan kullanıcılar da mesajı almaz. Bu kombinasyonlar, bu özelliği destekler:

  • TopicA ve TopicB
  • TopicA ve TopicC

Koşullu ifadenize en fazla beş konu ekleyebilirsiniz.

Bir koşula göndermek için:

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 komutu:

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

Sonraki adımlar