Inviare messaggi agli argomenti su Unity

In base al modello di pubblicazione/sottoscrizione, la FCM messaggistica argomento consente di inviare un messaggio a più dispositivi che hanno attivato un determinato argomento. Componi i messaggi degli argomenti in base alle esigenze e FCM gestisce il routing e l'invio affidabile dei messaggi ai dispositivi giusti.

Ad esempio, gli utenti di un'app di previsione delle maree locali potrebbero attivare un argomento "avvisi sulle correnti di marea" e ricevere notifiche sulle condizioni ottimali per la pesca in acqua salata in aree specifiche. Utenti di un'app di sport possono iscriversi per ricevere aggiornamenti automatici sui risultati delle partite live per team di sicurezza.

Alcuni aspetti da tenere presente in merito agli argomenti:

  • I messaggi di argomento sono più adatti per contenuti come il meteo o altre informazioni disponibili pubblicamente.
  • I messaggi topic sono ottimizzati per la velocità effettiva anziché per la latenza. Per l'invio rapido e sicuro su singoli dispositivi o piccoli gruppi di dispositivi, scegli come target dei messaggi i token di registrazione, non gli argomenti.
  • Se devi inviare messaggi a più dispositivi per utente, considera la possibilità messaggistica di gruppo di dispositivi per questi casi d'uso.
  • La messaggistica argomento supporta un numero illimitato di iscrizioni per ogni argomento. Tuttavia, FCM prevede limiti in queste aree:
    • Un'istanza dell'app può essere sottoscritta per non più di 2000 argomenti.
    • Se utilizzi l'importazione collettiva per abbonare le istanze dell'app, ogni richiesta è limitata a 1000 istanze.
    • La frequenza dei nuovi abbonamenti è limitata per progetto. Se invii troppe richieste di abbonamento in un breve periodo di tempo, i server FCM risponderanno con un messaggio 429 RESOURCE_EXHAUSTED ("quota superata"). Riprova con backoff esponenziale.

Sottoscrivere l'abbonamento dell'app client a un argomento

Per abbonarti a un argomento, chiama Firebase.Messaging.FirebaseMessaging.Subscribe dalla tua applicazione. Viene inviata una richiesta asincrona al backend FCM e il client viene iscritto all'argomento specificato.

Firebase.Messaging.FirebaseMessaging.Subscribe("/topics/example");

Se inizialmente la richiesta di abbonamento non va a buon fine, FCM riprova fino al giorno può iscriversi all'argomento correttamente. Ogni volta che l'app viene avviata, FCM si assicura che tutti gli argomenti richiesti siano stati sottoscritti.

Per annullare l'iscrizione, chiama Firebase.Messaging.FirebaseMessaging.Unsubscribe, e FCM annulla l'iscrizione all'argomento in background.

Gestisci sottoscrizioni agli argomenti sul server

Firebase Admin SDK consente di eseguire attività di gestione di base degli argomenti lato server. Dati i relativi token di registrazione, puoi sottoscrivere e annullare l'iscrizione collettiva delle istanze dell'app client utilizzando la logica del server.

Puoi abbonare le istanze dell'app client a qualsiasi argomento esistente o creare un nuovo argomento. Quando utilizzi l'API per abbonare un'app client a un nuovo argomento (che non esiste già per il tuo progetto Firebase), viene creato un nuovo argomento con quel nome in FCM e qualsiasi client può successivamente abbonarsi.

Puoi passare un elenco di token di registrazione a Firebase Admin SDK per sottoscrivere un abbonamento dei dispositivi corrispondenti a un argomento:

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

Vai

// 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 consente anche di annullare l'iscrizione dei dispositivi a un argomento passando i token di registrazione all'app :

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

Vai

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

I metodi subscribeToTopic() e unsubscribeFromTopic() generano un oggetto contenente la risposta di FCM. Il tipo restituito ha lo stesso a prescindere dal numero di token di registrazione specificato nel richiesta.

In caso di errore (errori di autenticazione, token o argomento non validi e così via) questi metodi generano un errore. Per un elenco completo dei codici di errore, incluse le descrizioni e i passaggi per la risoluzione, consulta Errori dell'API FCM Amministrazione.

Ricevere e gestire i messaggi degli argomenti

FCM consegna i messaggi degli argomenti come gli altri downstream messaggi.

Se ti abboni all'evento Firebase.Messaging.FirebaseMessaging.MessageReceived, puoi eseguire azioni in base al messaggio ricevuto e ottenere i dati del messaggio.

Firebase.Messaging.FirebaseMessaging.MessageReceived += OnMessageReceived;

...

public void OnMessageReceived(object sender, Firebase.Messaging.MessageReceivedEventArgs e) {
  UnityEngine.Debug.Log("Received a new message");
  if (e.Message.From.Length > 0)
    UnityEngine.Debug.Log("from: " + e.Message.From);
  if (e.Message.Data.Count > 0) {
    UnityEngine.Debug.Log("data:");
    foreach (System.Collections.Generic.KeyValuePair iter in
             e.Message.Data) {
      UnityEngine.Debug.Log("  " + iter.Key + ": " + iter.Value);
    }
  }
}

Crea richieste di invio

Dopo aver creato un argomento, sottoscrivendo le istanze dell'app client all'argomento sul lato client o tramite l'API server, puoi inviare messaggi all'argomento. Se è la prima volta che crei richieste di invio per FCM, consulta la guida relativa al tuo ambiente server e a FCM per informazioni importanti di contesto e configurazione.

Nella logica di invio sul backend, specifica il nome dell'argomento desiderato come mostrato:

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)

Vai

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

Comando 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

Per inviare un messaggio a una combinazione di argomenti, specifica una condizione, ovvero un'espressione booleana che specifica gli argomenti di destinazione. Ad esempio, la seguente condizione invierà messaggi ai dispositivi iscritti a TopicA e TopicB o TopicC:

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

FCM valuta prima eventuali condizioni tra parentesi, poi valuta l'espressione da sinistra a destra. Nell'espressione precedente, un utente iscritto a qualsiasi singolo argomento non riceve il messaggio. Allo stesso modo, un utente che non si iscrive a TopicA non riceve il messaggio. Queste combinazioni lo fanno ricevere:

  • TopicA e TopicB
  • TopicA e TopicC

Nell'espressione condizionale puoi includere fino a cinque argomenti.

Per inviare a una condizione:

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)

Vai

// 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",
    }
  }
}

Comando 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