Basée sur le modèle de publication/abonnement, la messagerie de sujet FCM vous permet d'envoyer un message à plusieurs appareils qui se sont inscrits à un sujet particulier. Vous rédigez des messages thématiques selon vos besoins, et FCM gère le routage et la transmission du message de manière fiable vers les bons appareils.
Par exemple, les utilisateurs d'une application locale de prévision des marées pourraient opter pour un sujet « alertes de courants de marée » et recevoir des notifications sur les conditions optimales de pêche en eau salée dans des zones spécifiées. Les utilisateurs d’une application sportive pourraient s’abonner à des mises à jour automatiques des scores en direct de leurs équipes préférées.
Quelques points à garder à l’esprit sur les sujets :
- La messagerie thématique est mieux adaptée au contenu tel que la météo ou d’autres informations accessibles au public.
- Les messages thématiques sont optimisés pour le débit plutôt que pour la latence . Pour une diffusion rapide et sécurisée sur des appareils uniques ou sur de petits groupes d'appareils, ciblez les messages sur des jetons d'enregistrement et non sur des sujets.
- Si vous devez envoyer des messages à plusieurs appareils par utilisateur , envisagez la messagerie de groupe d'appareils pour ces cas d'utilisation.
- La messagerie thématique prend en charge des abonnements illimités pour chaque sujet. Cependant, FCM impose des limites dans les domaines suivants :
- Une instance d’application ne peut pas être abonnée à plus de 2 000 sujets.
- Si vous utilisez l'importation par lots pour abonner des instances d'application, chaque demande est limitée à 1 000 instances d'application.
- La fréquence des nouveaux abonnements est limitée par projet. Si vous envoyez trop de demandes d'abonnement sur une courte période, les serveurs FCM répondront avec une réponse
429 RESOURCE_EXHAUSTED
(« quota dépassé »). Réessayez avec une interruption exponentielle.
Abonnez l'application client à un sujet
Les applications clientes peuvent s'abonner à n'importe quel sujet existant ou créer un nouveau sujet. Lorsqu'une application client s'abonne à un nouveau nom de sujet (qui n'existe pas déjà pour votre projet Firebase), un nouveau sujet de ce nom est créé dans FCM et n'importe quel client peut ensuite s'y abonner.
Pour vous abonner à une rubrique, appelez la méthode d'abonnement depuis le thread principal de votre application (FCM n'est pas thread-safe). Si la demande d'abonnement échoue initialement, FCM réessaye automatiquement. Dans les cas où l'abonnement ne peut pas être complété, l'abonnement génère une erreur que vous pouvez détecter dans un gestionnaire d'achèvement, comme indiqué :
Rapide
Messaging.messaging().subscribe(toTopic: "weather") { error in print("Subscribed to weather topic") }
Objectif c
[[FIRMessaging messaging] subscribeToTopic:@"weather" completion:^(NSError * _Nullable error) { NSLog(@"Subscribed to weather topic"); }];
Cet appel effectue une requête asynchrone au backend FCM et abonne le client à la rubrique donnée. Avant d'appeler subscribeToTopic:topic
, assurez-vous que l'instance d'application cliente a déjà reçu un jeton d'enregistrement via le rappel didReceiveRegistrationToken
.
Chaque fois que l'application démarre, FCM s'assure que tous les sujets demandés ont été abonnés. Pour vous désabonner, appelez unsubscribeFromTopic:topic
et FCM se désabonne du sujet en arrière-plan.
Gérer les abonnements aux sujets sur le serveur
Le SDK Firebase Admin vous permet d'effectuer des tâches de gestion de sujets de base côté serveur. Compte tenu de leur(s) jeton(s) d'enregistrement, vous pouvez abonner et désabonner des instances d'application client en masse à l'aide de la logique du serveur.
Vous pouvez abonner des instances d'application client à n'importe quelle rubrique existante ou créer une nouvelle rubrique. Lorsque vous utilisez l'API pour abonner une application client à un nouveau sujet (qui n'existe pas déjà pour votre projet Firebase), un nouveau sujet de ce nom est créé dans FCM et n'importe quel client peut ensuite s'y abonner.
Vous pouvez transmettre une liste de jetons d'enregistrement à la méthode d'abonnement au SDK d'administration Firebase pour abonner les appareils correspondants à un sujet :
Noeud.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')
Aller
// 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");
L'API Admin FCM vous permet également de désabonner des appareils d'un sujet en transmettant les jetons d'inscription à la méthode appropriée :
Noeud.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')
Aller
// 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");
Les méthodes subscribeToTopic()
et unsubscribeFromTopic()
génèrent un objet contenant la réponse de FCM. Le type de retour a le même format quel que soit le nombre de jetons d'enregistrement spécifié dans la requête.
En cas d'erreur (échecs d'authentification, jeton ou sujet non valide, etc.), ces méthodes entraînent une erreur. Pour obtenir la liste complète des codes d'erreur, y compris les descriptions et les étapes de résolution, consultez Erreurs de l'API Admin FCM .
Recevoir et gérer les messages thématiques
FCM transmet les messages thématiques de la même manière que les autres messages en aval.
Implémentez application(_:didReceiveRemoteNotification:fetchCompletionHandler:)
comme indiqué :
Rapide
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 }
Objectif 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); }
Créer des demandes d'envoi
Après avoir créé un sujet, soit en abonnant les instances d'application client au sujet côté client, soit via l' API du serveur , vous pouvez envoyer des messages au sujet. Si c'est la première fois que vous créez des requêtes d'envoi pour FCM, consultez le guide de votre environnement de serveur et de FCM pour obtenir des informations de base et de configuration importantes.
Dans votre logique d'envoi sur le backend, spécifiez le nom du sujet souhaité comme indiqué :
Noeud.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)
Aller
// 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);
REPOS
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"
}
}
}
Commande 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
Pour envoyer un message à une combinaison de rubriques, spécifiez une condition , qui est une expression booléenne qui spécifie les rubriques cibles. Par exemple, la condition suivante enverra des messages aux appareils abonnés à TopicA
et TopicB
ou TopicC
:
"'TopicA' in topics && ('TopicB' in topics || 'TopicC' in topics)"
FCM évalue d’abord les conditions entre parenthèses, puis évalue l’expression de gauche à droite. Dans l'expression ci-dessus, un utilisateur abonné à un seul sujet ne reçoit pas le message. De même, un utilisateur non abonné à TopicA
ne reçoit pas le message. Ces combinaisons le reçoivent :
-
TopicA
etTopicB
-
TopicA
etTopicC
Vous pouvez inclure jusqu'à cinq sujets dans votre expression conditionnelle.
Pour envoyer à une condition :
Noeud.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)
Aller
// 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);
REPOS
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",
}
}
}
Commande 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
Prochaines étapes
- En savoir plus sur l'autre façon d'envoyer vers plusieurs appareils : Messagerie de groupe d'appareils