Build app server send requests

Using the Firebase Admin SDK or FCM app server protocols,
you can build message requests and send them to these types of targets:

Topic name

Condition

Device registration token

Device group name (legacy protocols and Firebase Admin SDK for Node.js only)

You can send messages with a notification payload made up
of predefined fields, a data payload of your own user-defined fields, or a
message containing both types of payload.
See
Message types for more information.

Important: Send requests for both the Firebase Admin SDK and v1 HTTP protocol
must contain the project ID of the Firebase project for
your app, available in the General project settings tab of the Firebase console. Also, both methods of sending messages require you
to authorize send requests.

Send messages to specific devices

To send to a single, specific device, pass the device's registration token as
shown. See the client setup information for your platform to learn more about
registration tokens.

On success, each send method returns a message ID. The Firebase Admin SDK returns
the ID string in the format projects/{project_id}/messages/{message_id}.
The HTTP protocol response is a single JSON key:

This operation uses the sendAll() API under the hood, as shown in
the examples below. The return value
is a BatchResponse whose responses list corresponds to the order of the
input tokens. This is useful when you want to check which tokens resulted
in errors.

To send a message to a combination of topics,
specify a condition, which is a boolean expression that specifies the
target topics. For example, the following condition will send messages to
devices that are subscribed to TopicA and either TopicB or TopicC:

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

FCM first evaluates any conditions in parentheses, and then evaluates
the expression from left to right. In the above expression, a user subscribed to
any single topic does not receive the message. Likewise, a user who does not
subscribe to TopicA does not receive the message. These combinations do
receive it:

TopicA and TopicB

TopicA and TopicC

You can include up to five topics in your conditional expression.

To send to a condition:

Node.js

// 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 = {
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.
admin.messaging().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(new Notification(
"$GOOG up 1.43% on the day",
"$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day."))
.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)

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

Send a batch of messages

The Admin SDKs for Node and Java support sending messages in batches.
You can group up to 100
messages into a single batch and send them all in a single API call, with
significant performance improvement over sending separate HTTP requests for
each message.

This feature can be used to build a customized set of messages and send them
to different recipients, including topics or specific device registration tokens.
Use this feature when, for example, you need to
simultaneously send messages to different audiences with slightly different
details in the message body.

You can query the returned BatchResponse to check how many of the
messages were handed off to FCM successfully. It also exposes a list of
reponses that can be used to check the state of individual messages.
The order of the responses corresponds to the order of the messages
in the input list.

Customize messages across platforms

The Firebase Admin SDK and the FCM v1 HTTP protocol both allow your message
requests to set all fields available in the
message
object. This includes:

a common set of fields to be interpreted by all app instances that
receive the message.

platform-specific sets of fields, such as AndroidConfig and WebpushConfig,
interpreted only by app instances running on the specified platform.

Platform-specific blocks give you flexibility to customize messages for
different platforms to ensure that they are handled correctly when received. The
FCM backend will take all specified parameters into account and customize the
message for each platform.

When to use common fields

Use common fields when you're:

Targeting app instances on all platforms — iOS, Android, and web

Sending messages to topics

All app instances, regardless of platform, can interpret the following common
fields:

When to use platform-specific fields

Use platform-specific fields when you want to:

Send fields only to particular platforms

Send platform-specific fields in addition to the common fields

Whenever you want to send values only to particular platforms, don't use
common fields; use platform-specific fields. For example, to send a notification
only to iOS and web but not to Android, you must use two separate sets of
fields, one for iOS and one for web.

When you are sending messages with specific
delivery options,
use platform-specific fields to set them.
You can specify different values per platform if
you want. However, even when you want to set essentially the same value across
platforms, you must use platform-specific fields. This is because each platform
may interpret the value slightly differently—for example, time-to-live is
set on Android as an expiration time in seconds, while on iOS it is set as an
expiration date.

Example: notification message with platform-specific delivery options

The following send request sends a common notification title and content to all
platforms, but it also sends some platform-specific overrides. Specifically, the
request:

Sets a long time-to-live for Android, along with a special icon and color to
display on Android devices.

Sets the iOS-only badge field in the APNs payload, for delivery to
iOS devices.

The data message payload contains an invalid key. See the reference
documentation for
DataMessagePayload for restricted keys.

messaging/payload-size-limit-exceeded

The provided message payload exceeds the FCM size limits. The
limit is 4096 bytes for most messages. For messages sent to topics,
the limit is 2048 bytes. The
total payload size includes both keys and values.

Invalid registration token provided. Make sure it matches the registration
token the client app receives from registering with FCM. Do not
truncate or add additional characters to it.

messaging/registration-token-not-registered

The provided registration token is not registered. A previously valid
registration token can be unregistered for a variety of reasons,
including:

The client app unregistered itself from FCM.

The client app was automatically unregistered. This can happen if
the user uninstalls the application or, on iOS, if the APNS Feedback
Service reported the APNS token as invalid.

The registration token expired. For example, Google might decide to
refresh registration tokens or the APNS token may have expired for
iOS devices.

The client app was updated, but the new version is not configured to
receive messages.

For all these cases, remove this registration token and stop using it to
send messages.

messaging/invalid-package-name

The message was addressed to a registration token whose package name does
not match the provided
restrictedPackageName option.

messaging/message-rate-exceeded

The rate of messages to a particular target is too high. Reduce the number
of messages sent to this device or topic and do not immediately retry
sending to this target.

messaging/device-message-rate-exceeded

The rate of messages to a particular device is too high. Reduce the number
of messages sent to this device and do not immediately retry sending to
this device.

messaging/topics-message-rate-exceeded

The rate of messages to subscribers to a particular topic is too high.
Reduce the number of messages sent for this topic, and do not immediately
retry sending to this topic.

messaging/too-many-topics

A registration token has been subscribed to the maximum number of topics
and cannot be subscribed to any more.

messaging/invalid-apns-credentials

A message targeted to an iOS device could not be sent because the
required APNs SSL certificate was not uploaded or has expired. Check the
validity of your development and production certificates.

messaging/mismatched-credential

The credential used to authenticate this SDK does not have permission to
send messages to the device corresponding to the provided registration
token. Make sure the credential and registration token both belong to the
same Firebase project. See
Add Firebase to your
app for documentation on how to authenticate the Firebase Admin SDKs.

messaging/authentication-error

The SDK could not authenticate to the FCM servers. Make sure you
authenticate the Firebase Admin SDK with a credential which has the proper
permissions to send FCM messages. See
Add Firebase to your
app for documentation on how to authenticate the Firebase Admin SDKs.

messaging/server-unavailable

The FCM server could not process the request in time. You should
retry the same request, but you must:

Honor the Retry-After header if it is included in the
response from the FCM Connection Server.

Implement exponential back-off in your retry mechanism. For example,
if you waited one second before the first retry, wait at least two
seconds before the next one, then four seconds, and so on. If you're
sending multiple messages, delay each one independently by an
additional random amount to avoid issuing a new request for all
messages at the same time.

Senders that cause problems risk being blacklisted.

messaging/internal-error

The FCM server encountered an error while trying to process the
request. You could retry the same request following the requirements
listed in the messaging/server-unavailable row above. If the
error persists, please report the problem to our
Bug Report support channel.

messaging/unknown-error

An unknown server error was returned. See the raw server response in the
error message for more details. If you receive this error, please report
the full error message to our
Bug Report support channel.

Send messages using the legacy app server protocols

If you prefer to use the legacy protocols, build message requests as shown in
this section. Keep in mind that, if you are sending to multiple platforms via
HTTP, the v1 protocol can simplify your message requests.

Send messages to specific devices

To send messages to specific devices, set the to key to the registration
token for the specific app instance. See the client setup information for your
platform to learn more about registration tokens.

For the full list of message options available when sending downstream
messages to client apps, see the reference information for your chosen
connection server protocol,
HTTP or
XMPP.

Send messages to topics

Sending messages to a Firebase Cloud Messaging topic is very similar to
sending messages to an individual device or to a user group. The app
server sets the to key with a value like /topics/yourTopic.
Developers can
choose any topic name that matches the regular expression:
"/topics/[a-zA-Z0-9-_.~%]+".

To send to combinations of multiple topics, the app server must set the
condition key (instead of the to key) to a boolean condition that
specifies the target topics. For example, to send messages to devices that subscribed
to TopicA and either TopicB or
TopicC:

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

FCM first evaluates any conditions in parentheses, and then
evaluates the expression from left to right. In the above expression, a
user subscribed to any single topic does not
receive the message. Likewise, a user who does not subscribe to TopicA
does not receive the message. These combinations do receive it:

TopicA and TopicB

TopicA and TopicC

You can include up to five topics in your conditional expression, and parentheses are supported.
Supported operators: &&, ||, !. Note the usage
for !:

!('TopicA' in topics)

With this expression, any app instances that are not subscribed to TopicA,
including app instances that are not subscribed to any topic, receive the message.

For more detail about
app server keys, see the reference information for your chosen connection server
protocol,
HTTP or XMPP.
Examples in this page show how to send messages to topics in both HTTP and
XMPP.

Topic XMPP response

Expect up to 30 seconds of delay before the FCM Server
returns a success or failure response to the topic send requests. Make sure
to set the app server's timeout value in the request accordingly.

For the full list of message options, see the reference information for your chosen
connection server protocol,
HTTP or XMPP.

Note: It's also possible to target messages to multiple topics by setting
the condition key. For more information, see the topic messaging guide
for your platform.

Send messages to device groups

Sending messages to a device group is very similar to sending
messages to an individual device. Set the to parameter
to the unique notification key for the device group. See
Message types for details on
payload support. Examples in this page show how to send data
messages to device groups in HTTP and XMPP protocols.

Device Group HTTP Response

Here is an example of "success"— the notification_key
has 2 registration tokens associated with it, and the message was
successfully sent to both of them:

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

Here is an example of "partial success" — the
notification_key has 3 registration tokens associated
with it. The message was successfully sent to 1 of the registration
tokens only. The response message lists the registration tokens
that failed to receive the message:

Device Group XMPP Response

When the message is sent to any one of the devices in the group
successfully, the XMPP connection server responds with an ACK. If
all messages sent to all devices in the group fail, XMPP connection
server responds with a NACK.

Here is an example of "success" — the notification_key
has 3 registration tokens associated with it, and the message was
successfully sent to all of them:

Here is an example of "partial success" — the
notification_key has 3 registration tokens associated
with it. The message was successfully sent to 1 of the registration
tokens only. The response message lists the registration tokens
that failed to receive the message:

When FCM connection server fails to deliver to
all devices in the group. App server will receive a nack response.

For the full list of message options, see the reference information
for your chosen connection server protocol, HTTP or
XMPP.

Firebase Admin SDK legacy send methods

The Firebase Admin Node.js SDK supports methods for sending
(FCM) messages based on the
Legacy FCM server API.
These methods accept different arguments compared to the send() method.
You should use the send() method whenever possible, and only use the
methods described in this page when sending messages to individual devices or
device groups.

Warning: These APIs are only available in the Admin Node.js SDK.

Send to individual devices

You can pass a registration token to the
sendToDevice()
method to send a message to that device:

Note: You can send messages to up to 1000 devices in a single request. If you
provide an array with over 1000 registration tokens, the request will fail with
a messaging/invalid-recipient error.

The sendToDevice() method returns a promise that is resolved with a
MessagingDevicesResponse
object containing the response from FCM. The return type has the same
format when passing a single registration token or an array of registration
tokens.

Some cases such as an authentication error or rate limiting cause the entirety
of the message to fail to process. In these cases, the promise returned by
sendToDevice() is rejected with an error. For a full list of error codes,
including descriptions and resolution steps, see
Admin FCM API Errors.

Send to a device group

Device group messaging allows you to add multiple devices to a single group.
This is similar to topic messaging, but includes authentication to ensure
that group membership is managed only by your
servers. For example, if you want to send different messages to different phone models, your
servers can add/remove registrations to the appropriate groups and send the appropriate
message to each group. Device group messaging differs from topic messaging in that it involves
managing device groups from your servers instead of directly within your application.

You can use device group messaging via the
legacy
XMPP or
HTTP protocols on your app server.
Firebase Admin SDK for Node.js
based on the
legacy protocols also provide device group messaging capabilities.
The maximum number of members allowed for a
notification key is 20.

You can create device groups and generate notification keys via an app server or
an Android client. See
Managing device groups
for details.

The
sendToDeviceGroup()
method allows you to send a message to a device group by specifying the
notification key for that device group:

The sendToDeviceGroup() method returns a promise that is resolved with a
MessagingDeviceGroupResponse
object containing the response from FCM.

Some cases such as an authentication error or rate limiting cause the entirety
of the message to fail to process. In these cases, the promise returned by
sendToDeviceGroup() is rejected with an error. For a full list of error codes,
including descriptions and resolution steps, see
Admin FCM API Errors.

Defining the message payload

The above methods based on the FCM legacy protocols
accept a message payload as their second argument and support
both
notification and data messages.
You can specify one or both message types by creating an object with the data
and / or notification keys. For example, here is how to define different types
of message payloads:

Notification message

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

Notification message payloads have a predefined subset of valid properties and
differ slightly depending on which mobile operating system you are targeting.
See the reference docs for
NotificationMessagePayload
for a full list.

Data message payloads are composed of custom key-value pairs with a few
restrictions, including the fact that all values must be strings. See the
reference docs for
DataMessagePayload
for a full list of restrictions.

Defining the message options

The above methods based on the FCM legacy protocols
accept an optional third argument specifying some options for
the message. For example, the following example sends a high priority message
to a device which expires after 24 hours: