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

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

  • שם הנושא
  • מַצָב
  • אסימון רישום מכשיר
  • שם קבוצת המכשיר (פרוטוקול בלבד)

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

דוגמאות בדף זה מראות כיצד לשלוח הודעות התראה באמצעות Firebase Admin SDK (שיש לו תמיכה ב- Node , Java , Python , C# ו- Go ) ובפרוטוקול v1 HTTP . יש גם הנחיות לשליחת הודעות באמצעות פרוטוקולי HTTP ו-XMPP הוצאו משימוש.

שלח הודעות למכשירים ספציפיים

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

Node.js

// This registration token comes from the client FCM SDKs.
const registrationToken = 'YOUR_REGISTRATION_TOKEN';

const message = {
  data: {
    score: '850',
    time: '2:45'
  },
  token: registrationToken
};

// Send a message to the device corresponding to the provided
// registration token.
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

// This registration token comes from the client FCM SDKs.
String registrationToken = "YOUR_REGISTRATION_TOKEN";

// See documentation on defining a message payload.
Message message = Message.builder()
    .putData("score", "850")
    .putData("time", "2:45")
    .setToken(registrationToken)
    .build();

// Send a message to the device corresponding to the provided
// registration token.
String response = FirebaseMessaging.getInstance().send(message);
// Response is a message ID string.
System.out.println("Successfully sent message: " + response);

פִּיתוֹן

# This registration token comes from the client FCM SDKs.
registration_token = 'YOUR_REGISTRATION_TOKEN'

# See documentation on defining a message payload.
message = messaging.Message(
    data={
        'score': '850',
        'time': '2:45',
    },
    token=registration_token,
)

# Send a message to the device corresponding to the provided
# registration token.
response = messaging.send(message)
# Response is a message ID string.
print('Successfully sent message:', response)

ללכת

// Obtain a messaging.Client from the App.
ctx := context.Background()
client, err := app.Messaging(ctx)
if err != nil {
	log.Fatalf("error getting Messaging client: %v\n", err)
}

// This registration token comes from the client FCM SDKs.
registrationToken := "YOUR_REGISTRATION_TOKEN"

// See documentation on defining a message payload.
message := &messaging.Message{
	Data: map[string]string{
		"score": "850",
		"time":  "2:45",
	},
	Token: registrationToken,
}

// Send a message to the device corresponding to the provided
// registration token.
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#

// This registration token comes from the client FCM SDKs.
var registrationToken = "YOUR_REGISTRATION_TOKEN";

// See documentation on defining a message payload.
var message = new Message()
{
    Data = new Dictionary<string, string>()
    {
        { "score", "850" },
        { "time", "2:45" },
    },
    Token = registrationToken,
};

// Send a message to the device corresponding to the provided
// registration token.
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":{
      "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
      "notification":{
        "body":"This is an FCM notification message!",
        "title":"FCM Message"
      }
   }
}

פקודת cURL:

curl -X POST -H "Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA" -H "Content-Type: application/json" -d '{
"message":{
   "notification":{
     "title":"FCM Message",
     "body":"This is an FCM Message"
   },
   "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
}}' https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send

עם הצלחה, כל שיטת שליחה מחזירה מזהה הודעה. Firebase Admin SDK מחזיר את מחרוזת המזהה בפורמט projects/{project_id}/messages/{message_id} . תגובת פרוטוקול HTTP היא מפתח JSON יחיד:

    {
      "name":"projects/myproject-b5ae1/messages/0:1500415314455276%31bd1c9631bd1c96"
    }

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

ממשקי ה-API של Admin FCM מאפשרים לך לשדר הודעה מרובה לרשימה של אסימוני רישום מכשיר. אתה יכול לציין עד 500 אסימוני רישום מכשיר לכל הזמנה.

Node.js

// Create a list containing up to 500 registration tokens.
// These registration tokens come from the client FCM SDKs.
const registrationTokens = [
  'YOUR_REGISTRATION_TOKEN_1',
  // …
  'YOUR_REGISTRATION_TOKEN_N',
];

const message = {
  data: {score: '850', time: '2:45'},
  tokens: registrationTokens,
};

getMessaging().sendMulticast(message)
  .then((response) => {
    console.log(response.successCount + ' messages were sent successfully');
  });

Java

// Create a list containing up to 500 registration tokens.
// These registration tokens come from the client FCM SDKs.
List<String> registrationTokens = Arrays.asList(
    "YOUR_REGISTRATION_TOKEN_1",
    // ...
    "YOUR_REGISTRATION_TOKEN_n"
);

MulticastMessage message = MulticastMessage.builder()
    .putData("score", "850")
    .putData("time", "2:45")
    .addAllTokens(registrationTokens)
    .build();
BatchResponse response = FirebaseMessaging.getInstance().sendMulticast(message);
// See the BatchResponse reference documentation
// for the contents of response.
System.out.println(response.getSuccessCount() + " messages were sent successfully");

פִּיתוֹן

# Create a list containing up to 500 registration tokens.
# These registration tokens come from the client FCM SDKs.
registration_tokens = [
    'YOUR_REGISTRATION_TOKEN_1',
    # ...
    'YOUR_REGISTRATION_TOKEN_N',
]

message = messaging.MulticastMessage(
    data={'score': '850', 'time': '2:45'},
    tokens=registration_tokens,
)
response = messaging.send_multicast(message)
# See the BatchResponse reference documentation
# for the contents of response.
print('{0} messages were sent successfully'.format(response.success_count))

ללכת

// Create a list containing up to 500 registration tokens.
// This registration tokens come from the client FCM SDKs.
registrationTokens := []string{
	"YOUR_REGISTRATION_TOKEN_1",
	// ...
	"YOUR_REGISTRATION_TOKEN_n",
}
message := &messaging.MulticastMessage{
	Data: map[string]string{
		"score": "850",
		"time":  "2:45",
	},
	Tokens: registrationTokens,
}

br, err := client.SendMulticast(context.Background(), message)
if err != nil {
	log.Fatalln(err)
}

// See the BatchResponse reference documentation
// for the contents of response.
fmt.Printf("%d messages were sent successfully\n", br.SuccessCount)

C#

// Create a list containing up to 500 registration tokens.
// These registration tokens come from the client FCM SDKs.
var registrationTokens = new List<string>()
{
    "YOUR_REGISTRATION_TOKEN_1",
    // ...
    "YOUR_REGISTRATION_TOKEN_n",
};
var message = new MulticastMessage()
{
    Tokens = registrationTokens,
    Data = new Dictionary<string, string>()
    {
        { "score", "850" },
        { "time", "2:45" },
    },
};

var response = await FirebaseMessaging.DefaultInstance.SendEachForMulticastAsync(message);
// See the BatchResponse reference documentation
// for the contents of response.
Console.WriteLine($"{response.SuccessCount} messages were sent successfully");

ערך ההחזרה הוא רשימה של אסימונים התואמת את סדר אסימוני הקלט. זה שימושי כאשר אתה רוצה לבדוק אילו אסימונים הובילו לשגיאות.

Node.js

// These registration tokens come from the client FCM SDKs.
const registrationTokens = [
  'YOUR_REGISTRATION_TOKEN_1',
  // …
  'YOUR_REGISTRATION_TOKEN_N',
];

const message = {
  data: {score: '850', time: '2:45'},
  tokens: registrationTokens,
};

getMessaging().sendMulticast(message)
  .then((response) => {
    if (response.failureCount > 0) {
      const failedTokens = [];
      response.responses.forEach((resp, idx) => {
        if (!resp.success) {
          failedTokens.push(registrationTokens[idx]);
        }
      });
      console.log('List of tokens that caused failures: ' + failedTokens);
    }
  });

Java

// These registration tokens come from the client FCM SDKs.
List<String> registrationTokens = Arrays.asList(
    "YOUR_REGISTRATION_TOKEN_1",
    // ...
    "YOUR_REGISTRATION_TOKEN_n"
);

MulticastMessage message = MulticastMessage.builder()
    .putData("score", "850")
    .putData("time", "2:45")
    .addAllTokens(registrationTokens)
    .build();
BatchResponse response = FirebaseMessaging.getInstance().sendMulticast(message);
if (response.getFailureCount() > 0) {
  List<SendResponse> responses = response.getResponses();
  List<String> failedTokens = new ArrayList<>();
  for (int i = 0; i < responses.size(); i++) {
    if (!responses.get(i).isSuccessful()) {
      // The order of responses corresponds to the order of the registration tokens.
      failedTokens.add(registrationTokens.get(i));
    }
  }

  System.out.println("List of tokens that caused failures: " + failedTokens);
}

פִּיתוֹן

# These registration tokens come from the client FCM SDKs.
registration_tokens = [
    'YOUR_REGISTRATION_TOKEN_1',
    # ...
    'YOUR_REGISTRATION_TOKEN_N',
]

message = messaging.MulticastMessage(
    data={'score': '850', 'time': '2:45'},
    tokens=registration_tokens,
)
response = messaging.send_multicast(message)
if response.failure_count > 0:
    responses = response.responses
    failed_tokens = []
    for idx, resp in enumerate(responses):
        if not resp.success:
            # The order of responses corresponds to the order of the registration tokens.
            failed_tokens.append(registration_tokens[idx])
    print('List of tokens that caused failures: {0}'.format(failed_tokens))

ללכת

// Create a list containing up to 500 registration tokens.
// This registration tokens come from the client FCM SDKs.
registrationTokens := []string{
	"YOUR_REGISTRATION_TOKEN_1",
	// ...
	"YOUR_REGISTRATION_TOKEN_n",
}
message := &messaging.MulticastMessage{
	Data: map[string]string{
		"score": "850",
		"time":  "2:45",
	},
	Tokens: registrationTokens,
}

br, err := client.SendMulticast(context.Background(), message)
if err != nil {
	log.Fatalln(err)
}

if br.FailureCount > 0 {
	var failedTokens []string
	for idx, resp := range br.Responses {
		if !resp.Success {
			// The order of responses corresponds to the order of the registration tokens.
			failedTokens = append(failedTokens, registrationTokens[idx])
		}
	}

	fmt.Printf("List of tokens that caused failures: %v\n", failedTokens)
}

C#

// These registration tokens come from the client FCM SDKs.
var registrationTokens = new List<string>()
{
    "YOUR_REGISTRATION_TOKEN_1",
    // ...
    "YOUR_REGISTRATION_TOKEN_n",
};
var message = new MulticastMessage()
{
    Tokens = registrationTokens,
    Data = new Dictionary<string, string>()
    {
        { "score", "850" },
        { "time", "2:45" },
    },
};

var response = await FirebaseMessaging.DefaultInstance.SendEachForMulticastAsync(message);
if (response.FailureCount > 0)
{
    var failedTokens = new List<string>();
    for (var i = 0; i < response.Responses.Count; i++)
    {
        if (!response.Responses[i].IsSuccess)
        {
            // The order of responses corresponds to the order of the registration tokens.
            failedTokens.Add(registrationTokens[i]);
        }
    }

    Console.WriteLine($"List of tokens that caused failures: {failedTokens}");
}

שלח הודעות לנושאים

לאחר שיצרת נושא, על ידי הרשמה למופעי אפליקציית לקוח לנושא בצד הלקוח או באמצעות ממשק 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

שלח הודעות לקבוצות מכשירים

כדי לשלוח הודעות לקבוצות מכשירים, השתמש ב-API של HTTP v1. אם אתה שולח כעת לקבוצות מכשירים באמצעות ממשקי ה-API של שליחת מדור קודם עבור HTTP או XMPP, או כל אחת מהגירסאות הישנות יותר של Firebase Admin SDK עבור Node.js המבוססות על הפרוטוקולים הישנים, אנו ממליצים בחום לעבור ל-HTTP v1 API בהזדמנות המוקדמת ביותר. ממשקי ה-API לשליחה מדור קודם יושבתו ויוסרו ביוני 2024.

שליחת הודעות לקבוצת מכשירים דומה מאוד לשליחת הודעות למכשיר בודד, תוך שימוש באותה שיטה לאשר בקשות שליחה . הגדר את שדה token למפתח ההתראה הקבוצתי:

מנוחה

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":{
      "token":"APA91bGHXQBB...9QgnYOEURwm0I3lmyqzk2TXQ",
      "data":{
        "hello": "This is a Firebase Cloud Messaging device group message!"
      }
   }
}

פקודת cURL

curl -X POST -H "Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA" -H "Content-Type: application/json" -d '{
"message":{
   "data":{
     "hello": "This is a Firebase Cloud Messaging device group message!"
   },
   "token":"APA91bGHXQBB...9QgnYOEURwm0I3lmyqzk2TXQ"
}}' https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send

שלח קבוצה של הודעות

ערכות ה-Admin SDK תומכות בשליחת הודעות באצווה. אתה יכול לקבץ עד 500 הודעות באצווה אחת ולשלוח את כולן בקריאת API אחת, עם שיפור משמעותי בביצועים לעומת שליחת בקשות HTTP נפרדות לכל הודעה.

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

Node.js

// Create a list containing up to 500 messages.
const messages = [];
messages.push({
  notification: { title: 'Price drop', body: '5% off all electronics' },
  token: registrationToken,
});
messages.push({
  notification: { title: 'Price drop', body: '2% off all books' },
  topic: 'readers-club',
});

getMessaging().sendAll(messages)
  .then((response) => {
    console.log(response.successCount + ' messages were sent successfully');
  });

Java

// Create a list containing up to 500 messages.
List<Message> messages = Arrays.asList(
    Message.builder()
        .setNotification(Notification.builder()
            .setTitle("Price drop")
            .setBody("5% off all electronics")
            .build())
        .setToken(registrationToken)
        .build(),
    // ...
    Message.builder()
        .setNotification(Notification.builder()
            .setTitle("Price drop")
            .setBody("2% off all books")
            .build())
        .setTopic("readers-club")
        .build()
);

BatchResponse response = FirebaseMessaging.getInstance().sendAll(messages);
// See the BatchResponse reference documentation
// for the contents of response.
System.out.println(response.getSuccessCount() + " messages were sent successfully");

פִּיתוֹן

# Create a list containing up to 500 messages.
messages = [
    messaging.Message(
        notification=messaging.Notification('Price drop', '5% off all electronics'),
        token=registration_token,
    ),
    # ...
    messaging.Message(
        notification=messaging.Notification('Price drop', '2% off all books'),
        topic='readers-club',
    ),
]

response = messaging.send_all(messages)
# See the BatchResponse reference documentation
# for the contents of response.
print('{0} messages were sent successfully'.format(response.success_count))

ללכת

// Create a list containing up to 500 messages.
messages := []*messaging.Message{
	{
		Notification: &messaging.Notification{
			Title: "Price drop",
			Body:  "5% off all electronics",
		},
		Token: registrationToken,
	},
	{
		Notification: &messaging.Notification{
			Title: "Price drop",
			Body:  "2% off all books",
		},
		Topic: "readers-club",
	},
}

br, err := client.SendAll(context.Background(), messages)
if err != nil {
	log.Fatalln(err)
}

// See the BatchResponse reference documentation
// for the contents of response.
fmt.Printf("%d messages were sent successfully\n", br.SuccessCount)

C#

// Create a list containing up to 500 messages.
var messages = new List<Message>()
{
    new Message()
    {
        Notification = new Notification()
        {
            Title = "Price drop",
            Body = "5% off all electronics",
        },
        Token = registrationToken,
    },
    new Message()
    {
        Notification = new Notification()
        {
            Title = "Price drop",
            Body = "2% off all books",
        },
        Topic = "readers-club",
    },
};

var response = await FirebaseMessaging.DefaultInstance.SendEachAsync(messages);
// See the BatchResponse reference documentation
// for the contents of response.
Console.WriteLine($"{response.SuccessCount} messages were sent successfully");

שלח הודעות התומכות באתחול ישיר (אנדרואיד בלבד)

אתה יכול לשלוח הודעות למכשירים במצב אתחול ישיר באמצעות HTTP v1 או HTTP API מדור קודם. לפני שליחה למכשירים במצב אתחול ישיר, ודא שהשלמת את השלבים כדי לאפשר למכשירי לקוח לקבל הודעות FCM במצב אתחול ישיר .

שלח באמצעות FCM v1 HTTP API

בקשת ההודעה חייבת לכלול את המפתח "direct_boot_ok" : true באפשרויות AndroidConfig של גוף הבקשה. לדוגמה:

https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send
Content-Type:application/json
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA

{
  "message":{
    "token" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
    "data": {
      "score": "5x1",
      "time": "15:10"
    },
    "android": {
      "direct_boot_ok": true,
    },
}

שלח באמצעות FCM HTTP API מדור קודם

בקשת ההודעה חייבת לכלול את המפתח "direct_boot_ok" : true ברמה העליונה של גוף הבקשה. לדוגמה:

https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA

{ "data": {
    "score": "5x1",
    "time": "15:10"
  },
  "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
  "direct_boot_ok" : true
}

הודעות שנשלחות עם מפתח זה בגוף הבקשה יכולות להיות מטופלות על ידי אפליקציות במכשירים שנמצאים כרגע במצב אתחול ישיר (וגם כשלא במצב זה).

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

Firebase Admin SDK ופרוטוקול HTTP v1 FCM מאפשרים לבקשות ההודעה שלך להגדיר את כל השדות הזמינים באובייקט message . זה כולל:

  • קבוצה משותפת של שדות שיתפרשו על ידי כל מופעי האפליקציה שמקבלים את ההודעה.
  • קבוצות שדות ספציפיות לפלטפורמה, כגון AndroidConfig ו- WebpushConfig , המתפרשות רק על ידי מופעי אפליקציה הפועלים בפלטפורמה שצוינה.

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

מתי להשתמש בשדות נפוצים

השתמש בשדות נפוצים כאשר אתה:

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

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

מתי להשתמש בשדות ספציפיים לפלטפורמה

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

  • שלח שדות רק לפלטפורמות מסוימות
  • שלח שדות ספציפיים לפלטפורמה בנוסף לשדות הנפוצים

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

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

דוגמה: הודעת התראה עם אפשרויות צבע וסמלים

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

עבור אנדרואיד, הבקשה מגדירה סמל וצבע מיוחדים שיוצגו במכשירי אנדרואיד. כפי שצוין בהפניה ל- AndroidNotification , הצבע מצוין בפורמט #rrggbb, והתמונה חייבת להיות משאב אייקון שניתן לצייר מקומי לאפליקציית Android.

להלן הערכה של האפקט החזותי במכשיר של משתמש:

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

Node.js

const topicName = 'industry-tech';

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.'
  },
  android: {
    notification: {
      icon: 'stock_ticker_update',
      color: '#7e55c3'
    }
  },
  topic: topicName,
};

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

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())
    .setAndroidConfig(AndroidConfig.builder()
        .setTtl(3600 * 1000)
        .setNotification(AndroidNotification.builder()
            .setIcon("stock_ticker_update")
            .setColor("#f45342")
            .build())
        .build())
    .setApnsConfig(ApnsConfig.builder()
        .setAps(Aps.builder()
            .setBadge(42)
            .build())
        .build())
    .setTopic("industry-tech")
    .build();

פִּיתוֹן

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.',
    ),
    android=messaging.AndroidConfig(
        ttl=datetime.timedelta(seconds=3600),
        priority='normal',
        notification=messaging.AndroidNotification(
            icon='stock_ticker_update',
            color='#f45342'
        ),
    ),
    apns=messaging.APNSConfig(
        payload=messaging.APNSPayload(
            aps=messaging.Aps(badge=42),
        ),
    ),
    topic='industry-tech',
)

ללכת

oneHour := time.Duration(1) * time.Hour
badge := 42
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.",
	},
	Android: &messaging.AndroidConfig{
		TTL: &oneHour,
		Notification: &messaging.AndroidNotification{
			Icon:  "stock_ticker_update",
			Color: "#f45342",
		},
	},
	APNS: &messaging.APNSConfig{
		Payload: &messaging.APNSPayload{
			Aps: &messaging.Aps{
				Badge: &badge,
			},
		},
	},
	Topic: "industry-tech",
}

C#

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.",
    },
    Android = new AndroidConfig()
    {
        TimeToLive = TimeSpan.FromHours(1),
        Notification = new AndroidNotification()
        {
            Icon = "stock_ticker_update",
            Color = "#f45342",
        },
    },
    Apns = new ApnsConfig()
    {
        Aps = new Aps()
        {
            Badge = 42,
        },
    },
    Topic = "industry-tech",
};

מנוחה

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":"industry-tech",
     "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."
     },
     "android":{
       "notification":{
         "icon":"stock_ticker_update",
         "color":"#7e55c3"
       }
     }
   }
 }

עיין בתיעוד ההפניה של HTTP v1 לקבלת פרטים מלאים על המפתחות הזמינים בלוקים ספציפיים לפלטפורמה בגוף ההודעה.

דוגמה: הודעת התראה עם תמונה מותאמת אישית

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

ציור פשוט של תמונה בהודעת תצוגה

Node.js

const topicName = 'industry-tech';

const message = {
  notification: {
    title: 'Sparky says hello!'
  },
  android: {
    notification: {
      imageUrl: 'https://foo.bar.pizza-monster.png'
    }
  },
  apns: {
    payload: {
      aps: {
        'mutable-content': 1
      }
    },
    fcm_options: {
      image: 'https://foo.bar.pizza-monster.png'
    }
  },
  webpush: {
    headers: {
      image: 'https://foo.bar.pizza-monster.png'
    }
  },
  topic: topicName,
};

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

מנוחה

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":"industry-tech",
     "notification":{
       "title":"Sparky says hello!",
     },
     "android":{
       "notification":{
         "image":"https://foo.bar/pizza-monster.png"
       }
     },
     "apns":{
       "payload":{
         "aps":{
           "mutable-content":1
         }
       },
       "fcm_options": {
           "image":"https://foo.bar/pizza-monster.png"
       }
     },
     "webpush":{
       "headers":{
         "image":"https://foo.bar/pizza-monster.png"
       }
     }
   }
 }

עיין בתיעוד ההפניה של HTTP v1 לקבלת פרטים מלאים על המפתחות הזמינים בלוקים ספציפיים לפלטפורמה בגוף ההודעה.

דוגמה: הודעת התראה עם פעולת קליק משויכת

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

ציור פשוט של הקשה של משתמש בפתיחת דף אינטרנט

Node.js

const topicName = 'industry-tech';

const message = {
  notification: {
    title: 'Breaking News....'
  },
  android: {
    notification: {
      clickAction: 'news_intent'
    }
  },
  apns: {
    payload: {
      aps: {
        'category': 'INVITE_CATEGORY'
      }
    }
  },
  webpush: {
    fcmOptions: {
      link: 'breakingnews.html'
    }
  },
  topic: topicName,
};

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

מנוחה

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":"industry-tech",
     "notification":{
       "title":"Breaking News...",
     },
     "android":{
       "notification":{
         "click_action":"news_intent"
       }
     },
     "apns":{
       "payload":{
         "aps":{
           "category" : "INVITE_CATEGORY"
         }
       },
     },
     "webpush":{
       "fcm_options":{
         "link":"breakingnews.html"
       }
     }
   }
 }

עיין בתיעוד ההפניה של HTTP v1 לקבלת פרטים מלאים על המפתחות הזמינים בלוקים ספציפיים לפלטפורמה בגוף ההודעה.

דוגמה: הודעת התראה עם אפשרויות לוקליזציה

הדוגמה הבאה של בקשת שליחת שולחת אפשרויות לוקליזציה עבור הלקוח כדי להציג הודעות מקומיות. להלן הערכה של האפקט החזותי במכשיר של משתמש:

ציור פשוט של שני מכשירים המציגים טקסט באנגלית ובספרדית

Node.js

var topicName = 'industry-tech';

var message = {
  android: {
    ttl: 3600000,
    notification: {
      bodyLocKey: 'STOCK_NOTIFICATION_BODY',
      bodyLocArgs: ['FooCorp', '11.80', '835.67', '1.43']
    }
  },
  apns: {
    payload: {
      aps: {
        alert: {
          locKey: 'STOCK_NOTIFICATION_BODY',
          locArgs: ['FooCorp', '11.80', '835.67', '1.43']
        }
      }
    }
  },
  topic: topicName,
};

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

מנוחה

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":"Tech",
             "android":{
               "ttl":"3600s",
               "notification":{
                 "body_loc_key": "STOCK_NOTIFICATION_BODY",
                 "body_loc_args":  ["FooCorp", "11.80", "835.67", "1.43"],
               },
             },
             "apns":{
               "payload":{
                 "aps":{
                   "alert" : {
                     "loc-key": "STOCK_NOTIFICATION_BODY",
                     "loc-args":  ["FooCorp", "11.80", "835.67", "1.43"],
                    },
                 },
               },
             },
  },
}'

עיין בתיעוד ההפניה של HTTP v1 לקבלת פרטים מלאים על המפתחות הזמינים בלוקים ספציפיים לפלטפורמה בגוף ההודעה.

קודי שגיאה של REST עבור ה-API של HTTP v1

תגובות שגיאת HTTP עבור ה-API של HTTP v1 מכילות קוד שגיאה, הודעת שגיאה וסטטוס שגיאה. הם עשויים להכיל גם מערך details עם פרטים נוספים על השגיאה.

להלן שתי תגובות שגיאה לדוגמה:

דוגמה 1: תגובת שגיאה מבקשת HTTP v1 API עם ערך לא חוקי בהודעת נתונים

{
  "error": {
    "code": 400,
    "message": "Invalid value at 'message.data[0].value' (TYPE_STRING), 12",
    "status": "INVALID_ARGUMENT",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.BadRequest",
        "fieldViolations": [
          {
            "field": "message.data[0].value",
            "description": "Invalid value at 'message.data[0].value' (TYPE_STRING), 12"
          }
        ]
      }
    ]
  }
}

דוגמה 2: תגובת שגיאה מבקשת HTTP v1 API עם אסימון רישום לא חוקי

{
  "error": {
    "code": 400,
    "message": "The registration token is not a valid FCM registration token",
    "status": "INVALID_ARGUMENT",
    "details": [
      {
        "@type": "type.googleapis.com/google.firebase.fcm.v1.FcmError",
        "errorCode": "INVALID_ARGUMENT"
      }
    ]
   }
}

שימו לב שלשתי ההודעות יש את אותו הקוד והסטטוס, אך מערך הפרטים מכיל ערכים מסוגים שונים. בדוגמה הראשונה יש את הסוג type.googleapis.com/google.rpc.BadRequest המציין שגיאה בערכי הבקשה. בדוגמה השנייה עם הסוג type.googleapis.com/google.firebase.fcm.v1.FcmError יש שגיאה ספציפית ל-FCM. עבור שגיאות רבות, מערך הפרטים מכיל את המידע שתצטרך כדי לנפות באגים ולמצוא פתרון.

הטבלה הבאה מפרטת את קודי השגיאה של FCM v1 REST API ואת התיאורים שלהם.

קוד שגיאה שלבי תיאור ופתרון
UNSPECIFIED_ERROR אין מידע נוסף על שגיאה זו. אף אחד.
INVALID_ARGUMENT (קוד שגיאה HTTP = 400) פרמטרי הבקשה לא היו חוקיים. הרחבה מסוג google.rpc.BadRequest מוחזרת כדי לציין איזה שדה היה לא חוקי. סיבות אפשריות כוללות רישום לא חוקי, שם חבילה לא חוקי, הודעה גדולה מדי, מפתח נתונים לא חוקי, TTL לא חוקי או פרמטרים לא חוקיים אחרים.
רישום לא חוקי : בדוק את הפורמט של אסימון הרישום שאתה מעביר לשרת. ודא שהוא תואם את אסימון הרישום שאפליקציית הלקוח מקבלת מההרשמה ל-FCM. אין לקצץ את האסימון או להוסיף תווים נוספים.
שם חבילה לא חוקי : ודא שההודעה הופנתה לאסימון רישום ששם החבילה שלו תואם לערך שהועבר בבקשה.
הודעה גדולה מדי : בדוק שהגודל הכולל של נתוני המטען הכלולים בהודעה אינו חורג ממגבלות FCM: 4096 בתים עבור רוב ההודעות, או 2048 בייטים במקרה של הודעות לנושאים. זה כולל גם את המפתחות וגם את הערכים.
מפתח נתונים לא חוקי : בדוק שנתוני המטען אינם מכילים מפתח (כגון מ, או gcm, או כל ערך עם קידומת google) שנמצא בשימוש פנימי על ידי FCM. שים לב שמילים מסוימות (כגון collapse_key) משמשות גם את FCM אך מותרות במטען, ובמקרה זה ערך המטען יעקוף על ידי ערך FCM.
TTL לא חוקי : בדוק שהערך בשימוש ב-ttl הוא מספר שלם המייצג משך בשניות בין 0 ל-2,419,200 (4 שבועות).
פרמטרים לא חוקיים : בדוק שלפרמטרים שסופקו יש את השם והסוג הנכונים.
UNREGISTERED (קוד שגיאה HTTP = 404) מופע האפליקציה לא נרשם מ-FCM. זה בדרך כלל אומר שהאסימון שבו נעשה שימוש כבר אינו תקף ויש להשתמש באחד חדש. שגיאה זו יכולה להיגרם עקב חסרים אסימוני רישום, או אסימונים לא רשומים.
רישום חסר : אם יעד ההודעה הוא ערך token , בדוק שהבקשה מכילה אסימון רישום.
לא רשום : אסימון רישום קיים עלול להפסיק להיות תקף במספר תרחישים, כולל:
- אם אפליקציית הלקוח מבטלת את הרישום ב-FCM.
- אם אפליקציית הלקוח בוטלה באופן אוטומטי, מה שיכול לקרות אם המשתמש מסיר את ההתקנה של האפליקציה. לדוגמה, ב-iOS, אם שירות המשוב של ה-APN דיווח על אסימון ה-APN כלא חוקי.
- אם תוקף אסימון הרישום פג (לדוגמה, Google עשויה להחליט לרענן אסימוני רישום, או שתוקף אסימון ה-APNs פג עבור מכשירי iOS).
- אם אפליקציית הלקוח מעודכנת אך הגרסה החדשה אינה מוגדרת לקבלת הודעות.
בכל המקרים הללו, הסר אסימון רישום זה משרת האפליקציה והפסק להשתמש בו לשליחת הודעות.
SENDER_ID_MISMATCH (קוד שגיאה HTTP = 403) מזהה השולח המאומת שונה מזהה השולח עבור אסימון הרישום. אסימון רישום קשור לקבוצה מסוימת של שולחים. כאשר אפליקציית לקוח נרשמה ל-FCM, עליה לציין אילו שולחים רשאים לשלוח הודעות. עליך להשתמש באחד מאותם מזהי שולח בעת שליחת הודעות לאפליקציית הלקוח. אם תעבור לשולח אחר, אסימוני הרישום הקיימים לא יפעלו.
QUOTA_EXCEEDED (קוד שגיאה HTTP = 429) חרגת ממגבלת השליחה עבור יעד ההודעה. הרחבה מסוג google.rpc.QuotaFailure מוחזרת כדי לציין איזו מכסה חרגה. שגיאה זו יכולה להיגרם עקב חריגה ממכסת תעריף הודעות, חריגה ממכסת תעריף הודעות במכשיר או חריגה ממכסת תעריף הודעות בנושא.
חריגה מקצב ההודעות : קצב שליחת ההודעות גבוה מדי. עליך להפחית את הקצב הכולל שבו אתה שולח הודעות. השתמש ב-backoff אקספוננציאלי עם עיכוב ראשוני מינימלי של דקה אחת כדי לנסות שוב הודעות שנדחו.
חריגה משיעור ההודעות במכשיר : שיעור ההודעות למכשיר מסוים גבוה מדי. ראה מגבלת שיעור הודעות למכשיר בודד . צמצם את מספר ההודעות שנשלחות למכשיר זה והשתמש ב-backoff אקספוננציאלי כדי לנסות לשלוח שוב.
חריגה משיעור הודעות הנושא : שיעור ההודעות למנויים לנושא מסוים גבוה מדי. צמצם את מספר ההודעות שנשלחו עבור נושא זה והשתמש ב-backoff אקספוננציאלי עם עיכוב ראשוני מינימלי של דקה אחת כדי לנסות לשלוח שוב.
UNAVAILABLE (קוד שגיאה HTTP = 503) השרת עמוס יתר על המידה. השרת לא הצליח לעבד את הבקשה בזמן. נסה שוב את אותה בקשה, אך עליך:
- כבד את הכותרת של ניסיון חוזר לאחר אם היא כלולה בתגובה משרת החיבורים של FCM.
- יישם גיבוי אקספוננציאלי במנגנון הניסיון החוזר שלך. (לדוגמה, אם חיכית שנייה אחת לפני הניסיון החוזר הראשון, המתן לפחות שתי שניות לפני הבא, ואז 4 שניות וכן הלאה). אם אתה שולח מספר הודעות, שקול להחיל ריצוד. למידע נוסף, ראה טיפול בניסיונות חוזרים . שולחים שגורמים לבעיות מסתכנים בדחיית הרשימה.
INTERNAL (קוד שגיאה HTTP = 500) אירעה שגיאה פנימית לא ידועה. השרת נתקל בשגיאה בעת ניסיון לעבד את הבקשה. תוכל לנסות שוב את אותה בקשה בעקבות הצעות בטיפול בניסיונות חוזרים . אם השגיאה נמשכת, פנה לתמיכה של Firebase.
THIRD_PARTY_AUTH_ERROR (קוד שגיאה HTTP = 401) אישור APN או מפתח אישור דחיפה באינטרנט לא היה חוקי או חסר. לא ניתן לשלוח הודעה הממוקדת למכשיר iOS או רישום דחיפה באינטרנט. בדוק את תקפות אישורי הפיתוח והייצור שלך.

קודי שגיאה של מנהל מערכת

הטבלה הבאה מפרטת את קודי השגיאה של Firebase Admin FCM API ואת התיאורים שלהם, כולל שלבי פתרון מומלצים.

קוד שגיאה שלבי תיאור ופתרון
messaging/invalid-argument ארגומנט לא חוקי סופק לשיטת FCM. הודעת השגיאה צריכה להכיל מידע נוסף.
messaging/invalid-recipient נמען ההודעה המיועד אינו חוקי. הודעת השגיאה צריכה להכיל מידע נוסף.
messaging/invalid-payload סופק אובייקט מטען לא חוקי של הודעה. הודעת השגיאה צריכה להכיל מידע נוסף.
messaging/invalid-data-payload-key מטען הודעת הנתונים מכיל מפתח לא חוקי. עיין בתיעוד העיון עבור DataMessagePayload עבור מפתחות מוגבלים.
messaging/payload-size-limit-exceeded עומס ההודעות שסופק חורג ממגבלות הגודל של FCM. המגבלה היא 4096 בתים עבור רוב ההודעות. עבור הודעות שנשלחות לנושאים, המגבלה היא 2048 בתים. גודל המטען הכולל כולל מפתחות וערכים.
messaging/invalid-options סופק אובייקט אפשרויות הודעה לא חוקי. הודעת השגיאה צריכה להכיל מידע נוסף.
messaging/invalid-registration-token סופק אסימון רישום לא חוקי. ודא שהוא תואם את אסימון הרישום שאפליקציית הלקוח מקבלת מההרשמה ל-FCM. אין לקטוע או להוסיף לו תווים נוספים.
messaging/registration-token-not-registered אסימון הרישום שסופק אינו רשום. ניתן לבטל רישום של אסימון רישום תקף בעבר ממגוון סיבות, כולל:
  • אפליקציית הלקוח ביטלה את עצמה מ-FCM.
  • אפליקציית הלקוח בוטלה באופן אוטומטי. זה יכול לקרות אם המשתמש מסיר את ההתקנה של האפליקציה או, בפלטפורמות של Apple, אם שירות המשוב של ה-APN דיווח על אסימון ה-APN כלא חוקי.
  • פג תוקף אסימון הרישום. לדוגמה, Google עשויה להחליט לרענן אסימוני רישום או שאסימון APNs פג עבור מכשירי אפל.
  • אפליקציית הלקוח עודכנה, אך הגרסה החדשה אינה מוגדרת לקבל הודעות.
בכל המקרים הללו, הסר אסימון רישום זה והפסק להשתמש בו לשליחת הודעות.
messaging/invalid-package-name ההודעה הופנתה לאסימון רישום ששם החבילה שלו אינו תואם לאפשרות restrictedPackageName שסופקה.
messaging/message-rate-exceeded שיעור ההודעות אל יעד מסוים גבוה מדי. צמצם את מספר ההודעות שנשלחו למכשיר או לנושא זה ואל תנסה לשלוח שוב מיד ליעד זה.
messaging/device-message-rate-exceeded קצב ההודעות למכשיר מסוים גבוה מדי. צמצם את מספר ההודעות שנשלחו למכשיר זה ואל תנסה לשלוח מחדש מיד למכשיר זה.
messaging/topics-message-rate-exceeded שיעור ההודעות למנויים לנושא מסוים גבוה מדי. צמצם את מספר ההודעות שנשלחו עבור נושא זה, ואל תנסה לשלוח שוב מיד לנושא זה.
messaging/too-many-topics אסימון רישום נרשם למספר המרבי של נושאים ולא ניתן להירשם אליו יותר.
messaging/invalid-apns-credentials לא ניתן לשלוח הודעה המיועדת למכשיר אפל מכיוון שאישור ה-SSL של APNs הנדרש לא הועלה או שפג תוקפו. בדוק את תוקף תעודות הפיתוח והייצור שלך.
messaging/mismatched-credential לאישור המשמש לאימות SDK זה אין הרשאה לשלוח הודעות למכשיר התואמות לאסימון הרישום שסופק. ודא שהאישור ואסימון הרישום שייכים שניהם לאותו פרויקט Firebase. ראה הוסף Firebase לאפליקציה שלך לתיעוד על אופן האימות של Firebase Admin SDKs.
messaging/authentication-error ה-SDK לא הצליח לבצע אימות לשרתי FCM. ודא שאתה מאמת את Firebase Admin SDK עם אישור בעל ההרשאות המתאימות לשלוח הודעות FCM. ראה הוסף Firebase לאפליקציה שלך לתיעוד על אופן האימות של Firebase Admin SDKs.
messaging/server-unavailable שרת FCM לא הצליח לעבד את הבקשה בזמן. עליך לנסות שוב את אותה בקשה, אך עליך:
  • כבד את הכותרת Retry-After אם היא כלולה בתגובה משרת החיבורים של FCM.
  • יישם גיבוי אקספוננציאלי במנגנון הניסיון החוזר שלך. לדוגמה, אם חיכית שנייה אחת לפני הניסיון החוזר הראשון, המתן לפחות שתי שניות לפני הבא, לאחר מכן ארבע שניות וכן הלאה. אם אתה שולח מספר הודעות, דחה כל אחת בנפרד בסכום אקראי נוסף כדי להימנע מהוצאת בקשה חדשה עבור כל ההודעות בו-זמנית.
שולחים שגורמים לבעיות מסתכנים ברשימה השחורה.
messaging/internal-error שרת FCM נתקל בשגיאה בעת ניסיון לעבד את הבקשה. אתה יכול לנסות שוב את אותה בקשה בהתאם לדרישות המפורטות בשורה messaging/server-unavailable למעלה. אם השגיאה נמשכת, אנא דווח על הבעיה לערוץ התמיכה של דיווח באגים שלנו.
messaging/unknown-error הוחזרה שגיאת שרת לא ידועה. ראה את תגובת השרת הגולמית בהודעת השגיאה לפרטים נוספים. אם אתה מקבל שגיאה זו, אנא דווח על הודעת השגיאה המלאה לערוץ התמיכה של דיווח באגים שלנו.

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

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

שלח הודעות למכשירים ספציפיים

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

בקשת HTTP POST

https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA

{ "data": {
    "score": "5x1",
    "time": "15:10"
  },
  "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
}

תגובת HTTP

{ "multicast_id": 108,
  "success": 1,
  "failure": 0,
  "results": [
    { "message_id": "1:08" }
  ]
}

הודעת XMPP

<message id="">
  <gcm xmlns="google:mobile:data">
    { "data": {
      "score": "5x1",
      "time": "15:10"
    },
    "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
  }
  </gcm>
</message>

תגובת XMPP

<message id="">
  <gcm xmlns="google:mobile:data">
  {
      "from":"REGID",
      "message_id":"m-1366082849205"
      "message_type":"ack"
  }
  </gcm>
</message>

שרת החיבור XMPP מספק כמה אפשרויות אחרות לתגובות. ראה פורמט תגובת שרת .

לרשימה המלאה של אפשרויות ההודעות הזמינות בעת שליחת הודעות במורד הזרם לאפליקציות לקוח, עיין במידע ההפניה עבור פרוטוקול שרת החיבור שבחרת, HTTP או XMPP .

שלח הודעות לנושאים

שליחת הודעות לנושא Firebase Cloud Messaging דומה מאוד לשליחת הודעות למכשיר בודד או לקבוצת משתמשים. שרת האפליקציה מגדיר את מפתח to עם ערך כמו /topics/yourTopic . מפתחים יכולים לבחור כל שם נושא שתואם לביטוי הרגולרי: "/topics/[a-zA-Z0-9-_.~%]+" .

כדי לשלוח לשילובים של מספר נושאים, שרת האפליקציה חייב להגדיר את מפתח condition (במקום מקש to ) למצב בוליאני המציין את נושאי היעד. לדוגמה, כדי לשלוח הודעות למכשירים שנרשמו TopicA ולנושא TopicB או TopicC :

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

FCM מעריך תחילה תנאים בסוגריים, ולאחר מכן מעריך את הביטוי משמאל לימין. בביטוי שלמעלה, משתמש שנרשם לאף נושא בודד אינו מקבל את ההודעה. כמו כן, משתמש שאינו מנוי ל-TopicA אינו מקבל את ההודעה. השילובים האלה אכן מקבלים את זה:

  • נושא א' ונושא ב'
  • TopicA ו- TopicC

אתה יכול לכלול עד חמישה נושאים בביטוי המותנה שלך, וסוגריים נתמכים. אופרטורים נתמכים: && , || .

בקשת HTTP POST בנושא

שלח לנושא בודד:

https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA


שלח למכשירים הרשומים לנושאים "כלבים" או "חתולים":

https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA


תגובת HTTP בנושא

// Success example:
{
  "message_id": "1023456"
}

// failure example:
{
  "error": "TopicsMessageRateExceeded"
}

הודעת XMPP בנושא

שלח לנושא בודד:

<message id="">
  <gcm xmlns="google:mobile:data">


  </gcm>
</message>

שלח למכשירים הרשומים לנושאים "כלבים" או "חתולים":

<message id="">
  <gcm xmlns="google:mobile:data">


  </gcm>
</message>

תגובת XMPP בנושא

// Success example:
{
  "message_id": "1023456"
}

// failure example:
{
  "error": "TopicsMessageRateExceeded"
}

צפה של עיכוב של עד 30 שניות לפני ששרת FCM יחזיר תגובת הצלחה או כישלון לבקשות שליחת הנושא. הקפד להגדיר את ערך הזמן הקצוב של שרת האפליקציה בבקשה בהתאם.

שלח הודעות לקבוצות מכשירים

שליחת הודעות לקבוצת מכשירים באמצעות ממשקי API מדור קודם דומה מאוד לשליחת הודעות למכשיר בודד. הגדר את הפרמטר to למפתח ההתראה הייחודי עבור קבוצת המכשירים. דוגמאות בסעיף זה מראות כיצד לשלוח הודעות נתונים לקבוצות מכשירים בפרוטוקולי HTTP ו-XMPP הישנים.

בקשת HTTP POST של קבוצת מכשירים

https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA

{
  "to": "aUniqueKey",
  "data": {
    "hello": "This is a Firebase Cloud Messaging Device Group Message!",
   }
}

תגובת HTTP של קבוצת מכשירים

הנה דוגמה ל"הצלחה" - ל- notification_key יש 2 אסימוני רישום המשויכים אליו, וההודעה נשלחה בהצלחה לשניהם:

{
  "success": 2,
  "failure": 0
}

הנה דוגמה ל"הצלחה חלקית" - ל- notification_key יש 3 אסימוני רישום המשויכים אליו. ההודעה נשלחה בהצלחה לאחד מאסימוני הרישום בלבד. הודעת התגובה מפרטת את אסימוני הרישום ( registration_ids ) שלא הצליחו לקבל את ההודעה:

{
  "success":1,
  "failure":2,
  "failed_registration_ids":[
     "regId1",
     "regId2"
  ]
}

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

אם השרת מנסה לשלוח הודעה לקבוצת מכשירים שאין בה חברים, התגובה נראית כך, עם 0 הצלחה ו-0 כישלון:

{
  "success": 0,
  "failure": 0
}

הודעת XMPP של קבוצת התקנים

<message id="">
  <gcm xmlns="google:mobile:data">
  {
      "to": "aUniqueKey",
      "message_id": "m-1366082849205" ,
      "data": {
          "hello":"This is a Firebase Cloud Messaging Device Group Message!"
      }
  }
  </gcm>
</message>

תגובת XMPP של קבוצת מכשירים

כאשר ההודעה נשלחת לאחד מהמכשירים בקבוצה בהצלחה, שרת החיבור XMPP מגיב ב-ACK. אם כל ההודעות שנשלחו לכל המכשירים בקבוצה נכשלות, שרת החיבור של XMPP מגיב ב-NACK.

הנה דוגמה ל"הצלחה" - ל- notification_key יש 3 אסימוני רישום המשויכים אליו, וההודעה נשלחה בהצלחה לכולם:

{
  "from": "aUniqueKey",
  "message_type": "ack",
  "success": 3,
  "failure": 0,
  "message_id": "m-1366082849205"
}

הנה דוגמה ל"הצלחה חלקית" - ל- notification_key יש 3 אסימוני רישום המשויכים אליו. ההודעה נשלחה בהצלחה לאחד מאסימוני הרישום בלבד. הודעת התגובה מפרטת את אסימוני הרישום שלא הצליחו לקבל את ההודעה:

{
  "from": "aUniqueKey",
  "message_type": "ack",
  "success":1,
  "failure":2,
  "failed_registration_ids":[
     "regId1",
     "regId2"
  ]
}

כאשר שרת החיבור של FCM לא מצליח לספק לכל המכשירים בקבוצה. שרת האפליקציה יקבל תגובת nack.

לרשימה המלאה של אפשרויות ההודעה, עיין במידע ההפניה עבור פרוטוקול שרת החיבור שבחרת, HTTP או XMPP .

שיטות שליחת Firebase Admin SDK מדור קודם

Firebase Admin Node.js SDK תומך בשיטות לשליחת הודעות (FCM) המבוססות על ה- API של שרת FCM מדור קודם . שיטות אלו מקבלים ארגומנטים שונים בהשוואה לשיטת send() . עליך להשתמש בשיטת send() בכל הזדמנות אפשרית, ולהשתמש רק בשיטות המתוארות בדף זה בעת שליחת הודעות למכשירים בודדים או לקבוצות מכשירים.

שלח למכשירים בודדים

אתה יכול להעביר אסימון רישום לשיטת sendToDevice() כדי לשלוח הודעה לאותו מכשיר:

Node.js

// This registration token comes from the client FCM SDKs.
const registrationToken = 'bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...';

// See the "Defining the message payload" section below for details
// on how to define a message payload.
const payload = {
  data: {
    score: '850',
    time: '2:45'
  }
};

// Send a message to the device corresponding to the provided
// registration token.
getMessaging().sendToDevice(registrationToken, payload)
  .then((response) => {
    // See the MessagingDevicesResponse reference documentation for
    // the contents of response.
    console.log('Successfully sent message:', response);
  })
  .catch((error) => {
    console.log('Error sending message:', error);
  });

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

Node.js

// These registration tokens come from the client FCM SDKs.
const registrationTokens = [
  'bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...',
  // ...
  'ecupwIfBy1w:APA91bFtuMY7MktgxA3Au_Qx7cKqnf...'
];

// See the "Defining the message payload" section below for details
// on how to define a message payload.
const payload = {
  data: {
    score: '850',
    time: '2:45'
  }
};

// Send a message to the devices corresponding to the provided
// registration tokens.
getMessaging().sendToDevice(registrationTokens, payload)
  .then((response) => {
    // See the MessagingDevicesResponse reference documentation for
    // the contents of response.
    console.log('Successfully sent message:', response);
  })
  .catch((error) => {
    console.log('Error sending message:', error);
  });

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

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

שלח לקבוצת מכשירים

שיטת sendToDeviceGroup() מאפשרת לך לשלוח הודעה לקבוצת מכשירים על ידי ציון מפתח ההתראה עבור קבוצת המכשירים הזו:

Node.js

// See the "Managing device groups" link above on how to generate a
// notification key.
const notificationKey = 'some-notification-key';

// See the "Defining the message payload" section below for details
// on how to define a message payload.
const payload = {
  data: {
    score: '850',
    time: '2:45'
  }
};

// Send a message to the device group corresponding to the provided
// notification key.
getMessaging().sendToDeviceGroup(notificationKey, payload)
  .then((response) => {
    // See the MessagingDeviceGroupResponse reference documentation for
    // the contents of response.
    console.log('Successfully sent message:', response);
  })
  .catch((error) => {
    console.log('Error sending message:', error);
  });

השיטה sendToDeviceGroup() מחזירה הבטחה שנפתרה באמצעות אובייקט MessagingDevicesResponse המכיל את התגובה מ-FCM.

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

הגדרת מטען ההודעה

השיטות שלעיל המבוססות על פרוטוקולי FCM מדור קודם מקבלים מטען הודעות כארגומנט השני שלהם ותומכות הן בהודעות והן בהודעות נתונים . אתה יכול לציין סוג אחד או את שני ההודעות על ידי יצירת אובייקט עם מפתחות data ו/או notification . לדוגמה, הנה כיצד להגדיר סוגים שונים של מטענים של הודעות:

הודעת התראה

const payload = {
  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.'
  }
};

הודעת נתונים

const payload = {
  data: {
    score: '850',
    time: '2:45'
  }
};

הודעה משולבת

const payload = {
  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.'
  },
  data: {
    stock: 'GOOG',
    open: '829.62',
    close: '635.67'
  }
};

לעומסי הודעות התראה יש תת-קבוצה מוגדרת מראש של מאפיינים חוקיים והם שונים מעט בהתאם למערכת ההפעלה הניידת אליה אתה מכוון. עיין במסמכי העזר עבור NotificationMessagePayload לרשימה מלאה.

עומסי הודעות נתונים מורכבים מזוגות מפתח-ערך מותאמים אישית עם מספר הגבלות, כולל העובדה שכל הערכים חייבים להיות מחרוזות. עיין במסמכי העזר של DataMessagePayload לקבלת רשימה מלאה של הגבלות.

הגדרת אפשרויות ההודעה

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

Node.js

// This registration token comes from the client FCM SDKs.
const registrationToken = 'bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...';

// See the "Defining the message payload" section above for details
// on how to define a message payload.
const payload = {
  notification: {
    title: 'Urgent action needed!',
    body: 'Urgent action is needed to prevent your account from being disabled!'
  }
};

// Set the message as high priority and have it expire after 24 hours.
const options = {
  priority: 'high',
  timeToLive: 60 * 60 * 24
};

// Send a message to the device corresponding to the provided
// registration token with the provided options.
getMessaging().sendToDevice(registrationToken, payload, options)
  .then((response) => {
    console.log('Successfully sent message:', response);
  })
  .catch((error) => {
    console.log('Error sending message:', error);
  });

עיין במסמכי העזר עבור MessagingOptions לקבלת רשימה מלאה של אפשרויות זמינות.