앱 서버 전송 요청 작성

Firebase Admin SDK 또는 FCM 앱 서버 프로토콜을 사용하여 메시지 요청을 작성하고 다음과 같은 유형의 대상으로 전송할 수 있습니다.

  • 주제 이름
  • 조건
  • 기기 등록 토큰
  • 기기 그룹 이름(기존 프로토콜 및 Node.js용 Firebase Admin SDK만 해당)

사전 정의된 필드로 구성된 알림 페이로드 또는 사용자가 직접 정의한 필드로 구성된 데이터 페이로드와 함께 메시지를 보내거나 2가지 유형의 페이로드를 모두 포함하는 메시지를 보낼 수 있습니다. 자세한 내용은 메시지 유형을 참조하세요.

이 페이지의 예시에서는 Firebase Admin SDK(Node, 자바, Python, C#, Go 지원) 및 v1 HTTP 프로토콜을 사용하여 알림 메시지를 보내는 방법을 보여줍니다. 기존 HTTP 및 XMPP 프로토콜을 통해 메시지를 보내는 방법도 알아보세요.

특정 기기에 메시지 전송

특정 기기 1개에 메시지를 보내려면 아래와 같이 기기의 등록 토큰을 전달합니다. 등록 토큰에 대한 자세한 내용은 플랫폼별 클라이언트 설정 정보를 참조하세요.

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

Python

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

Go

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

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":{
      "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

성공하면 각 전송 메서드가 메시지 ID를 반환합니다. Firebase Admin SDK가 projects/{project_id}/messages/{message_id} 형식으로 ID 문자열을 반환합니다. HTTP 프로토콜 응답은 단일 JSON 키입니다.

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

여러 기기에 메시지 전송

REST API 및 Admin FCM API를 사용하면 기기 등록 토큰 목록에 메시지를 멀티캐스트할 수 있습니다. 호출당 최대 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");

Python

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

Go

// 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.SendMulticastAsync(message);
// See the BatchResponse reference documentation
// for the contents of response.
Console.WriteLine($"{response.SuccessCount} messages were sent successfully");

REST

HTTP 일괄 요청 생성:

--subrequest_boundary
Content-Type: application/http
Content-Transfer-Encoding: binary

POST /v1/projects/myproject-b5ae1/messages:send
Content-Type: application/json
accept: application/json

{
  "message":{
     "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
     "notification":{
       "title":"FCM Message",
       "body":"This is an FCM notification message!"
     }
  }
}

...

--subrequest_boundary
Content-Type: application/http
Content-Transfer-Encoding: binary

POST /v1/projects/myproject-b5ae1/messages:send
Content-Type: application/json
accept: application/json

{
  "message":{
     "token":"cR1rjyj4_Kc:APA91bGusqbypSuMdsh7jSNrW4nzsM...",
     "notification":{
       "title":"FCM Message",
       "body":"This is an FCM notification message!"
     }
  }
}
--subrequest_boundary--

요청을 파일에 저장합니다(이 예시에서는 batch_request.txt). 그런 다음 cURL 명령어를 사용합니다.

curl --data-binary @batch_request.txt -H 'Content-Type: multipart/mixed; boundary="subrequest_boundary"' -H 'Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA' https://fcm.googleapis.com/batch

Firebase Admin SDK의 경우 이 작업은 예와 같이 내부에서 sendAll() API를 사용합니다. 반환 값은 응답 목록이 입력 토큰 순서와 일치하는 BatchResponse입니다. 오류가 발생한 토큰을 확인하려는 경우에 유용합니다.

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

Python

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

Go

// 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.SendMulticastAsync(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}");
}

REST

각 전송 하위 전송이 응답을 반환합니다. 응답은 --batch_로 시작하는 응답 경계 문자열로 구분됩니다.

--batch_nDhMX4IzFTDLsCJ3kHH7v_44ua-aJT6q
Content-Type: application/http
Content-ID: response-

HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Vary: Origin
Vary: X-Origin
Vary: Referer

{
  "name": "projects/35006771263/messages/0:1570471792141125%43c11b7043c11b70"
}

...

--batch_nDhMX4IzFTDLsCJ3kHH7v_44ua-aJT6q
Content-Type: application/http
Content-ID: response-

HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Vary: Origin
Vary: X-Origin
Vary: Referer

{
  "name": "projects/35006771263/messages/0:1570471792141696%43c11b7043c11b70"
}

--batch_nDhMX4IzFTDLsCJ3kHH7v_44ua-aJT6q--

주제로 메시지 전송

주제를 만든 후에는 클라이언트 측의 클라이언트 앱 인스턴스에서 주제를 구독하거나 서버 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);

Python

# The topic name can be optionally prefixed with "/topics/".
topic = 'highScores'

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

# Send a message to the devices subscribed to the provided topic.
response = messaging.send(message)
# Response is a message ID string.
print('Successfully sent message:', response)

Go

// The topic name can be optionally prefixed with "/topics/".
topic := "highScores"

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

// Send a message to the devices subscribed to the provided topic.
response, err := client.Send(ctx, message)
if err != nil {
	log.Fatalln(err)
}
// Response is a message ID string.
fmt.Println("Successfully sent message:", response)

C#

// The topic name can be optionally prefixed with "/topics/".
var topic = "highScores";

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

// Send a message to the devices subscribed to the provided topic.
string response = await FirebaseMessaging.DefaultInstance.SendAsync(message);
// Response is a message ID string.
Console.WriteLine("Successfully sent message: " + response);

REST

POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1

Content-Type: application/json
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA
{
  "message":{
    "topic" : "foo-bar",
    "notification" : {
      "body" : "This is a Firebase Cloud Messaging Topic Message!",
      "title" : "FCM Message"
      }
   }
}

cURL 명령어:

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

조건식에 최대 5개의 주제를 포함할 수 있습니다.

조건으로 보내는 방법은 다음과 같습니다.

Node.js

// Define a condition which will send to devices which are subscribed
// to either the Google stock or the tech industry topics.
const condition = '\'stock-GOOG\' in topics || \'industry-tech\' in topics';

// See documentation on defining a message payload.
const message = {
  notification: {
    title: '$FooCorp up 1.43% on the day',
    body: '$FooCorp gained 11.80 points to close at 835.67, up 1.43% on the day.'
  },
  condition: condition
};

// Send a message to devices subscribed to the combination of topics
// specified by the provided condition.
getMessaging().send(message)
  .then((response) => {
    // Response is a message ID string.
    console.log('Successfully sent message:', response);
  })
  .catch((error) => {
    console.log('Error sending message:', error);
  });

Java

// Define a condition which will send to devices which are subscribed
// to either the Google stock or the tech industry topics.
String condition = "'stock-GOOG' in topics || 'industry-tech' in topics";

// See documentation on defining a message payload.
Message message = Message.builder()
    .setNotification(Notification.builder()
        .setTitle("$GOOG up 1.43% on the day")
        .setBody("$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.")
        .build())
    .setCondition(condition)
    .build();

// Send a message to devices subscribed to the combination of topics
// specified by the provided condition.
String response = FirebaseMessaging.getInstance().send(message);
// Response is a message ID string.
System.out.println("Successfully sent message: " + response);

Python

# Define a condition which will send to devices which are subscribed
# to either the Google stock or the tech industry topics.
condition = "'stock-GOOG' in topics || 'industry-tech' in topics"

# See documentation on defining a message payload.
message = messaging.Message(
    notification=messaging.Notification(
        title='$GOOG up 1.43% on the day',
        body='$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.',
    ),
    condition=condition,
)

# Send a message to devices subscribed to the combination of topics
# specified by the provided condition.
response = messaging.send(message)
# Response is a message ID string.
print('Successfully sent message:', response)

Go

// Define a condition which will send to devices which are subscribed
// to either the Google stock or the tech industry topics.
condition := "'stock-GOOG' in topics || 'industry-tech' in topics"

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

// Send a message to devices subscribed to the combination of topics
// specified by the provided condition.
response, err := client.Send(ctx, message)
if err != nil {
	log.Fatalln(err)
}
// Response is a message ID string.
fmt.Println("Successfully sent message:", response)

C#

// Define a condition which will send to devices which are subscribed
// to either the Google stock or the tech industry topics.
var condition = "'stock-GOOG' in topics || 'industry-tech' in topics";

// See documentation on defining a message payload.
var message = new Message()
{
    Notification = new Notification()
    {
        Title = "$GOOG up 1.43% on the day",
        Body = "$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.",
    },
    Condition = condition,
};

// Send a message to devices subscribed to the combination of topics
// specified by the provided condition.
string response = await FirebaseMessaging.DefaultInstance.SendAsync(message);
// Response is a message ID string.
Console.WriteLine("Successfully sent message: " + response);

REST

POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1

Content-Type: application/json
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA
{
   "message":{
    "condition": "'dogs' in topics || 'cats' in topics",
    "notification" : {
      "body" : "This is a Firebase Cloud Messaging Topic Message!",
      "title" : "FCM Message",
    }
  }
}

cURL 명령어:

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

일괄 메시지 전송

REST API와 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");

Python

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

Go

// 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.SendAllAsync(messages);
// See the BatchResponse reference documentation
// for the contents of response.
Console.WriteLine($"{response.SuccessCount} messages were sent successfully");

REST

하위 요청 목록을 결합하여 HTTP 일괄 요청 생성:

--subrequest_boundary
Content-Type: application/http
Content-Transfer-Encoding: binary

POST /v1/projects/myproject-b5ae1/messages:send
Content-Type: application/json
accept: application/json

{
  "message":{
     "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
     "notification":{
       "title":"FCM Message",
       "body":"This is an FCM notification message to device 0!"
     }
  }
}

--subrequest_boundary
Content-Type: application/http
Content-Transfer-Encoding: binary

POST /v1/projects/myproject-b5ae1/messages:send
Content-Type: application/json
accept: application/json

{
  "message":{
     "topic":"readers-club",
     "notification":{
       "title":"Price drop",
       "body":"2% off all books"
     }
  }
}

...

--subrequest_boundary
Content-Type: application/http
Content-Transfer-Encoding: binary

POST /v1/projects/myproject-b5ae1/messages:send
Content-Type: application/json
accept: application/json

{
  "message":{
     "token":"cR1rjyj4_Kc:APA91bGusqbypSuMdsh7jSNrW4nzsM...",
     "notification":{
       "title":"FCM Message",
       "body":"This is an FCM notification message to device N!"
     }
  }
}
--subrequest_boundary--

반환된 BatchResponse를 쿼리하여 FCM에 성공적으로 전달된 메시지 수를 확인할 수 있습니다. 개별 메시지의 상태를 확인하는 데 사용할 수 있는 응답 목록도 표시됩니다. 응답 순서는 입력 목록의 메시지 순서와 일치합니다.

직접 부팅이 사용 설정된 메시지 전송(Android만 해당)

HTTP v1 또는 기존 HTTP API를 사용하여 직접 부팅 모드의 기기로 메시지를 보낼 수 있습니다. 직접 부팅 모드의 기기로 메시지를 보내기 전에 클라이언트 기기가 직접 부팅 모드에서 FCM 메시지를 수신하는 단계를 완료했는지 확인하세요.

FCM v1 HTTP API를 사용하여 전송

메시지 요청에는 요청 본문의 AndroidConfig 옵션에 "direct_boot_ok" : true 키를 포함해야 합니다. 예를 들면 다음과 같습니다.

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 및 FCM v1 HTTP 프로토콜을 모두 사용하면 메시지 요청을 통해 message 객체에 제공되는 모든 필드를 설정할 수 있습니다. 여기에는 다음이 포함됩니다.

  • 메시지를 수신한 모든 앱 인스턴스에서 해석하는 공통 필드 모음
  • 지정된 플랫폼에서 실행되는 앱 인스턴스에서만 해석되는 AndroidConfigWebpushConfig와 같은 플랫폼별 필드 집합

플랫폼별 블록을 사용하면 수신 시 올바르게 처리할 수 있도록 다양한 플랫폼에 맞게 메시지를 유연하게 맞춤설정할 수 있습니다. FCM 백엔드는 지정된 모든 매개변수를 고려하여 각 플랫폼에 맞게 메시지를 맞춤설정합니다.

공통 필드를 사용해야 하는 경우

다음 작업에 공통 필드를 사용합니다.

  • Apple, Android, 웹 등 모든 플랫폼의 앱 인스턴스 타겟팅
  • 주제로 메시지 전송

플랫폼에 관계없이 모든 앱 인스턴스가 다음 공통 필드를 해석할 수 있습니다.

플랫폼별 필드를 사용해야 하는 경우

다음 작업을 하려면 플랫폼별 필드를 사용합니다.

  • 특정 플랫폼에만 필드 전송
  • 공통 필드 외에도 플랫폼별 필드 전송

특정 플랫폼에만 값을 보내려면 공통 필드를 사용하지 말고 플랫폼별 필드를 사용하세요. 예를 들어 Android를 제외한 Apple 플랫폼과 웹에만 알림을 보내려면 Apple 및 웹용으로 각각 하나씩 2개의 개별 필드 모음을 사용해야 합니다.

특정 전송 옵션으로 메시지를 보내는 경우에는 플랫폼별 필드를 사용하여 설정합니다. 원하는 경우 플랫폼별로 다른 값을 지정할 수 있지만 여러 플랫폼에 근본적으로 동일한 값을 설정하는 경우에도 플랫폼별 필드를 사용해야 합니다. 그 이유는 각 플랫폼에서 값을 약간씩 다르게 해석할 수 있기 때문입니다. 예를 들어 TTL(수명)이 Android에서는 만료 시간(초 단위)으로 설정되지만 Apple에서는 만료일로 설정됩니다.

예시: 색상 및 아이콘 옵션이 있는 알림 메시지

이 전송 요청 예시는 모든 플랫폼에 공통 알림 제목과 콘텐츠를 보내며 Android 기기에는 일부 플랫폼별 재정의도 보냅니다.

Android에서 이 요청은 Android 기기에 표시할 특수 아이콘과 색상을 설정합니다. 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();

Python

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

Go

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

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

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

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

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":"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 참조 문서를 확인하세요.

관리자 오류 코드

다음 표에는 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 크기 한도를 초과합니다. 대부분의 메시지는 4,096바이트로 제한됩니다. 주제로 보낸 메시지는 2,048바이트로 제한됩니다. 전체 페이로드 크기에는 키와 값이 모두 포함됩니다.
messaging/invalid-options 잘못된 메시지 옵션 객체가 제공되었습니다. 오류 메시지에 추가 정보가 들어 있습니다.
messaging/invalid-registration-token 잘못된 등록 토큰이 제공되었습니다. FCM에 등록할 때 클라이언트 앱이 수신하는 등록 토큰과 일치하는지 확인합니다. 문자를 자르거나 추가하지 마세요.
messaging/registration-token-not-registered 제공된 등록 토큰이 등록되지 않았습니다. 이전에 유효했던 등록 토큰이 다음을 비롯한 여러 가지 이유로 등록 취소되었을 수 있습니다.
  • 클라이언트 앱이 FCM에서 등록 취소되었습니다.
  • 클라이언트 앱이 자동으로 등록 취소되었습니다. 사용자가 애플리케이션을 제거했거나 Apple 플랫폼의 경우 APN 피드백 서비스에서 APN 토큰이 잘못되었다고 보고한 경우일 수 있습니다.
  • 등록 토큰이 만료되었습니다. 예를 들어 Google에서 등록 토큰 새로고침을 결정했거나 Apple 기기의 APN 토큰이 만료되었을 수 있습니다.
  • 클라이언트 앱이 업데이트되었지만 새 버전이 메시지를 수신하도록 구성되지 않았습니다.
위와 같은 경우에는 등록 토큰을 삭제하고 더 이상 메시지 전송에 사용하지 마세요.
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 필수 APN SSL 인증서가 업로드되지 않았거나 만료되어 Apple 기기를 대상으로 메시지를 보낼 수 없습니다. 개발 및 프로덕션 인증서의 유효성을 확인하세요.
messaging/mismatched-credential 이 SDK를 인증하는 데 사용된 인증 정보에, 제공된 등록 토큰에 해당하는 기기로 메시지를 보낼 권한이 없습니다. 인증 정보와 등록 토큰이 동일한 Firebase 프로젝트에 속하는지 확인하세요. Firebase Admin SDK를 인증하는 방법은 앱에 Firebase 추가를 참조하세요.
messaging/authentication-error SDK에서 FCM 서버에 인증할 수 없습니다. FCM 메시지를 보낼 적절한 권한이 있는 인증 정보를 사용하여 Firebase Admin SDK를 인증해야 합니다. Firebase Admin SDK를 인증하는 방법은 앱에 Firebase 추가를 참조하세요.
messaging/server-unavailable FCM 서버에서 시간 내에 요청을 처리하지 못했습니다. 동일한 요청을 다시 시도하되 다음을 수행해야 합니다.
  • FCM 연결 서버의 응답에 포함된 경우 Retry-After 헤더를 반영합니다.
  • 재시도 방식에서 지수 백오프를 구현합니다. 예를 들어 첫 번째 재시도 전에 1초 동안 기다렸다면 다음에는 2초, 다음에는 4초 동안 기다리는 식으로 대기 시간을 점차 늘립니다. 여러 메시지를 보내는 경우에는 모든 메시지를 동시에 새로 요청하지 않도록 메시지마다 개별적으로 무작위 지연 시간을 추가하세요.
문제를 유발하는 발신자는 차단될 수 있습니다.
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 클라우드 메시징 주제로 메시지를 보내는 것은 개별 기기나 사용자 그룹으로 메시지를 보내는 것과 매우 비슷합니다. 앱 서버는 to 키를 /topics/yourTopic과 같은 값으로 설정합니다. 개발자는 정규 표현식 "/topics/[a-zA-Z0-9-_.~%]+"와 일치하는 주제 이름을 선택할 수 있습니다.

여러 주제의 조합으로 전송하려면 앱 서버가 to 키 대신 condition 키를 대상 주제를 지정하는 불리언 조건으로 설정해야 합니다. 예를 들어 TopicA와 함께 TopicB 또는 TopicC에 구독된 기기로 메시지를 전송하려면 다음 안내를 따르세요.

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

FCM이 먼저 괄호의 모든 조건을 확인한 다음 왼쪽에서 오른쪽으로 표현식을 판정합니다. 위 표현식에서는 주제 1개를 구독한 사용자는 메시지를 수신하지 않습니다. 또한 TopicA를 구독하지 않은 사용자도 메시지를 수신하지 않습니다. 다음과 같이 조합되어야 메시지를 수신합니다.

  • TopicA 및 TopicB
  • TopicA 및 TopicC

조건식에 최대 5개의 주제를 포함할 수 있으며 괄호가 지원됩니다. 지원되는 연산자는 &&, ||입니다.

주제 HTTP POST 요청

주제 1개로 보내는 방법은 다음과 같습니다.

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

'dogs' 또는 'cats' 주제를 구독한 기기로 보내는 방법은 다음과 같습니다.

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 메시지

주제 1개로 보내는 방법은 다음과 같습니다.

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

  </gcm>
</message>

'dogs' 또는 'cats' 주제를 구독한 기기로 보내는 방법은 다음과 같습니다.

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

  </gcm>
</message>

주제 XMPP 응답

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

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

FCM 서버가 주제 전송 요청에 성공 또는 실패 응답을 반환하는 데 최대 30초의 지연이 발생할 수 있습니다. 요청에서 이 지연 시간에 맞게 앱 서버 제한 시간 값을 설정해야 합니다.

기기 그룹에 메시지 전송

기기 그룹에 메시지를 보내는 것은 개별 기기에 메시지를 보내는 것과 매우 비슷합니다. 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개 있습니다. 메시지가 등록 토큰 1개에만 성공적으로 전송되었습니다. 메시지를 수신하지 못한 등록 토큰(registration_ids)이 응답 메시지에 표시됩니다.

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

메시지가 notification_key에 연결된 등록 토큰 1개 이상에 전송되지 못하면 앱 서버에서 백오프를 두고 재시도하게 됩니다.

서버에서 메시지를 보내려는 기기 그룹에 구성원이 없는 경우 다음과 같이 응답의 성공, 실패가 모두 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개 있습니다. 메시지가 등록 토큰 1개에만 성공적으로 전송되었습니다. 메시지를 수신하지 못한 등록 토큰이 응답 메시지에 표시됩니다.

{
  "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() 메서드는 FCM의 응답이 포함된 MessagingDevicesResponse 객체로 확인되는 프로미스를 반환합니다. 반환 유형의 형식은 단일 등록 토큰 또는 등록 토큰 배열을 전달할 때와 동일합니다.

인증 오류 또는 비율 제한 등의 상황이 발생하면 전체 메시지 처리가 실패합니다. 이러한 경우 sendToDevice()이 반환하는 프로미스가 오류와 함께 거부됩니다. 설명 및 해결 단계가 포함된 전체 오류 코드 목록은 Admin FCM API 오류를 참조하세요.

기기 그룹으로 전송

기기 그룹 메시징을 사용하면 한 그룹에 여러 기기를 추가할 수 있습니다. 주제 메시징과 유사하지만 서버에서만 그룹 멤버십이 관리되도록 인증이 포함됩니다. 예를 들어 휴대전화 모델마다 다른 메시지를 보내려면 서버에서 알맞은 그룹에 등록을 추가/삭제하고 각 그룹에 적절한 메시지를 보내면 됩니다. 기기 그룹 메시징은 기기 그룹을 애플리케이션 내에서 직접 관리하는 것이 아니라 서버에서 관리한다는 점에서 주제 메시징과 다릅니다.

앱 서버에서 기존 XMPP 또는 HTTP 프로토콜을 통해 기기 그룹 메시징을 사용할 수 있습니다. 이전 버전의 Node.js용 Firebase Admin SDK는 기존 프로토콜을 기반으로 하고 기기 그룹 메시지 기능을 제공하기도 합니다. 알림 키 하나에 허용되는 최대 구성원 수는 20입니다.

앱 서버 또는 Android 클라이언트를 통해 기기 그룹을 만들고 알림 키를 생성할 수 있습니다. 자세한 내용은 기기 그룹 관리를 참조하세요.

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() 메서드는 FCM의 응답이 포함된 MessagingDevicesResponse 객체로 확인되는 프로미스를 반환합니다.

인증 오류 또는 비율 제한 등의 상황이 발생하면 전체 메시지 처리가 실패합니다. 이러한 경우 sendToDeviceGroup()이 반환하는 프로미스가 오류와 함께 거부됩니다. 설명 및 해결 단계가 포함된 전체 오류 코드 목록은 Admin FCM API 오류를 참조하세요.

메시지 페이로드 정의

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 참조 문서를 확인하세요.