Firebase Summit에서 발표된 모든 내용을 살펴보고 Firebase로 앱을 빠르게 개발하고 안심하고 앱을 실행하는 방법을 알아보세요. 자세히 알아보기

Android의 주제 메시징

발행/구독 모델을 기반으로 하는 FCM 주제 메시징을 사용하면 특정 주제에 옵트인한 여러 장치에 메시지를 보낼 수 있습니다. 필요에 따라 주제 메시지를 작성하면 FCM이 라우팅을 처리하고 메시지를 올바른 장치로 안정적으로 전달합니다.

예를 들어, 지역 조수 예측 앱 사용자는 "조수 경고" 주제를 선택하고 지정된 지역에서 최적의 바닷물 낚시 조건에 대한 알림을 받을 수 있습니다. 스포츠 앱 사용자는 좋아하는 팀의 실시간 경기 점수 자동 업데이트를 구독할 수 있습니다.

주제에 대해 염두에 두어야 할 몇 가지 사항:

  • 주제 메시징은 날씨 또는 기타 공개적으로 사용 가능한 정보와 같은 콘텐츠에 가장 적합합니다.
  • 주제 메시지는 대기 시간보다는 처리량에 최적화되어 있습니다. 단일 장치 또는 소규모 장치 그룹에 빠르고 안전하게 전달하려면 주제가 아닌 등록 토큰을 대상으로 메시지를 지정 합니다.
  • 사용자당 여러 장치에 메시지를 보내야 하는 경우 해당 사용 사례에 대해 장치 그룹 메시징 을 고려하십시오.
  • 주제 메시징은 각 주제에 대한 무제한 구독을 지원합니다. 그러나 FCM은 다음 영역에서 제한을 적용합니다.
    • 하나의 앱 인스턴스는 2000개 이하의 주제를 구독할 수 있습니다.
    • 일괄 가져오기 를 사용하여 앱 인스턴스를 구독하는 경우 각 요청은 1000개의 앱 인스턴스로 제한됩니다.
    • 새 구독 빈도는 프로젝트당 비율이 제한됩니다. 단기간에 너무 많은 구독 요청을 보내면 FCM 서버는 429 RESOURCE_EXHAUSTED ("할당량 초과") 응답으로 응답합니다. 지수 백오프로 재시도하십시오.

주제에 대한 클라이언트 앱 구독

클라이언트 앱은 기존 주제를 구독하거나 새 주제를 만들 수 있습니다. 클라이언트 앱이 새 주제 이름(Firebase 프로젝트에 아직 존재하지 않는 이름)을 구독하면 해당 이름의 새 주제가 FCM에 생성되고 모든 클라이언트가 이후에 구독할 수 있습니다.

주제를 구독하기 위해 클라이언트 앱은 FCM 주제 이름으로 Firebase 클라우드 메시징 subscribeToTopic() 을 호출합니다. 이 메서드는 완료 리스너에서 구독이 성공했는지 여부를 확인하는 데 사용할 수 있는 Task 를 반환합니다.

Java

FirebaseMessaging.getInstance().subscribeToTopic("weather")
        .addOnCompleteListener(new OnCompleteListener<Void>() {
            @Override
            public void onComplete(@NonNull Task<Void> task) {
                String msg = "Subscribed";
                if (!task.isSuccessful()) {
                    msg = "Subscribe failed";
                }
                Log.d(TAG, msg);
                Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
            }
        });

Kotlin+KTX

Firebase.messaging.subscribeToTopic("weather")
    .addOnCompleteListener { task ->
        var msg = "Subscribed"
        if (!task.isSuccessful) {
            msg = "Subscribe failed"
        }
        Log.d(TAG, msg)
        Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()
    }

구독을 취소하기 위해 클라이언트 앱은 주제 이름으로 Firebase 클라우드 메시징 unsubscribeFromTopic() 을 호출합니다.

서버에서 주제 구독 관리

Firebase Admin SDK 를 사용하면 서버 측에서 기본 주제 관리 작업을 수행할 수 있습니다. 등록 토큰이 주어지면 서버 로직을 사용하여 클라이언트 앱 인스턴스를 대량으로 구독 및 구독 취소할 수 있습니다.

클라이언트 앱 인스턴스를 기존 주제에 구독하거나 새 주제를 생성할 수 있습니다. API를 사용하여 클라이언트 앱에서 새 주제(Firebase 프로젝트에 아직 존재하지 않는 주제)를 구독하면 해당 이름의 새 주제가 FCM에 생성되고 모든 클라이언트가 이후에 구독할 수 있습니다.

등록 토큰 목록을 Firebase Admin SDK 구독 방법에 전달하여 해당 기기를 주제에 구독할 수 있습니다.

노드.js

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

// Subscribe the devices corresponding to the registration tokens to the
// topic.
getMessaging().subscribeToTopic(registrationTokens, topic)
  .then((response) => {
    // See the MessagingTopicManagementResponse reference documentation
    // for the contents of response.
    console.log('Successfully subscribed to topic:', response);
  })
  .catch((error) => {
    console.log('Error subscribing to topic:', error);
  });

자바

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

// Subscribe the devices corresponding to the registration tokens to the
// topic.
TopicManagementResponse response = FirebaseMessaging.getInstance().subscribeToTopic(
    registrationTokens, topic);
// See the TopicManagementResponse reference documentation
// for the contents of response.
System.out.println(response.getSuccessCount() + " tokens were subscribed successfully");

파이썬

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

# Subscribe the devices corresponding to the registration tokens to the
# topic.
response = messaging.subscribe_to_topic(registration_tokens, topic)
# See the TopicManagementResponse reference documentation
# for the contents of response.
print(response.success_count, 'tokens were subscribed successfully')

가다

// These registration tokens come from the client FCM SDKs.
registrationTokens := []string{
	"YOUR_REGISTRATION_TOKEN_1",
	// ...
	"YOUR_REGISTRATION_TOKEN_n",
}

// Subscribe the devices corresponding to the registration tokens to the
// topic.
response, err := client.SubscribeToTopic(ctx, registrationTokens, topic)
if err != nil {
	log.Fatalln(err)
}
// See the TopicManagementResponse reference documentation
// for the contents of response.
fmt.Println(response.SuccessCount, "tokens were subscribed successfully")

씨#

// These registration tokens come from the client FCM SDKs.
var registrationTokens = new List<string>()
{
    "YOUR_REGISTRATION_TOKEN_1",
    // ...
    "YOUR_REGISTRATION_TOKEN_n",
};

// Subscribe the devices corresponding to the registration tokens to the
// topic
var response = await FirebaseMessaging.DefaultInstance.SubscribeToTopicAsync(
    registrationTokens, topic);
// See the TopicManagementResponse reference documentation
// for the contents of response.
Console.WriteLine($"{response.SuccessCount} tokens were subscribed successfully");

Admin FCM API를 사용하면 등록 토큰을 적절한 방법으로 전달하여 주제에서 기기를 구독 취소할 수도 있습니다.

노드.js

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

// Unsubscribe the devices corresponding to the registration tokens from
// the topic.
getMessaging().unsubscribeFromTopic(registrationTokens, topic)
  .then((response) => {
    // See the MessagingTopicManagementResponse reference documentation
    // for the contents of response.
    console.log('Successfully unsubscribed from topic:', response);
  })
  .catch((error) => {
    console.log('Error unsubscribing from topic:', error);
  });

자바

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

// Unsubscribe the devices corresponding to the registration tokens from
// the topic.
TopicManagementResponse response = FirebaseMessaging.getInstance().unsubscribeFromTopic(
    registrationTokens, topic);
// See the TopicManagementResponse reference documentation
// for the contents of response.
System.out.println(response.getSuccessCount() + " tokens were unsubscribed successfully");

파이썬

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

# Unubscribe the devices corresponding to the registration tokens from the
# topic.
response = messaging.unsubscribe_from_topic(registration_tokens, topic)
# See the TopicManagementResponse reference documentation
# for the contents of response.
print(response.success_count, 'tokens were unsubscribed successfully')

가다

// These registration tokens come from the client FCM SDKs.
registrationTokens := []string{
	"YOUR_REGISTRATION_TOKEN_1",
	// ...
	"YOUR_REGISTRATION_TOKEN_n",
}

// Unsubscribe the devices corresponding to the registration tokens from
// the topic.
response, err := client.UnsubscribeFromTopic(ctx, registrationTokens, topic)
if err != nil {
	log.Fatalln(err)
}
// See the TopicManagementResponse reference documentation
// for the contents of response.
fmt.Println(response.SuccessCount, "tokens were unsubscribed successfully")

씨#

// These registration tokens come from the client FCM SDKs.
var registrationTokens = new List<string>()
{
    "YOUR_REGISTRATION_TOKEN_1",
    // ...
    "YOUR_REGISTRATION_TOKEN_n",
};

// Unsubscribe the devices corresponding to the registration tokens from the
// topic
var response = await FirebaseMessaging.DefaultInstance.UnsubscribeFromTopicAsync(
    registrationTokens, topic);
// See the TopicManagementResponse reference documentation
// for the contents of response.
Console.WriteLine($"{response.SuccessCount} tokens were unsubscribed successfully");

subscribeToTopic()unsubscribeFromTopic() 메서드는 FCM의 응답을 포함하는 객체를 생성합니다. 반환 유형은 요청에 지정된 등록 토큰 수에 관계없이 동일한 형식을 갖습니다.

오류(인증 실패, 유효하지 않은 토큰 또는 주제 등)의 경우 이러한 방법은 오류를 발생시킵니다. 설명 및 해결 단계를 포함한 전체 오류 코드 목록은 Admin FCM API 오류 를 참조하세요.

주제 메시지 수신 및 처리

FCM은 다른 다운스트림 메시지와 동일한 방식으로 주제 메시지를 전달합니다.

메시지를 수신하려면 FirebaseMessagingService 를 확장하는 서비스를 사용하십시오. 서비스는 onMessageReceivedonDeletedMessages 콜백을 재정의해야 합니다. 수신 후 20초(Android Marshmallow의 경우 10초) 이내에 모든 메시지를 처리해야 합니다. onMessageReceived 를 호출하기 전에 발생한 OS 지연에 따라 시간 창은 더 짧아질 수 있습니다. 그 이후에는 Android O의 백그라운드 실행 제한 과 같은 다양한 OS 동작으로 인해 작업을 완료하는 데 방해가 될 수 있습니다. 자세한 내용은 메시지 우선 순위 에 대한 개요를 참조하십시오.

onMessageReceived 는 다음을 제외하고 대부분의 메시지 유형에 제공됩니다.

  • 앱이 백그라운드에 있을 때 전달되는 알림 메시지 입니다. 이 경우 알림은 장치의 시스템 트레이로 전달됩니다. 사용자가 알림을 탭하면 기본적으로 앱 시작 관리자가 열립니다.

  • 백그라운드에서 수신될 때 알림 및 데이터 페이로드가 모두 포함된 메시지입니다 . 이 경우 알림은 장치의 시스템 트레이로 전달되고 데이터 페이로드는 런처 활동의 의도 외 추가로 전달됩니다.

요약해서 말하자면:

앱 상태 공고 데이터 둘 다
전경 onMessageReceived onMessageReceived onMessageReceived
배경 시스템 트레이 onMessageReceived 알림: 시스템 트레이
데이터: 의도 외
메시지 유형에 대한 자세한 내용은 알림 및 데이터 메시지 를 참조하십시오.

앱 매니페스트 수정

FirebaseMessagingService 를 사용하려면 앱 매니페스트에 다음을 추가해야 합니다.

<service
    android:name=".java.MyFirebaseMessagingService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

또한 알림의 모양을 사용자 지정하려면 기본값을 설정하는 것이 좋습니다. 알림 페이로드에 동등한 값이 설정되지 않을 때마다 적용되는 사용자 정의 기본 아이콘 및 사용자 정의 기본 색상을 지정할 수 있습니다.

사용자 정의 기본 아이콘 및 사용자 정의 색상을 설정하려면 application 태그 내에 다음 행을 추가하십시오.

<!-- Set custom default icon. This is used when no icon is set for incoming notification messages.
     See README(https://goo.gl/l4GJaQ) for more. -->
<meta-data
    android:name="com.google.firebase.messaging.default_notification_icon"
    android:resource="@drawable/ic_stat_ic_notification" />
<!-- Set color used with incoming notification messages. This is used when no color is set for the incoming
     notification message. See README(https://goo.gl/6BKBk7) for more. -->
<meta-data
    android:name="com.google.firebase.messaging.default_notification_color"
    android:resource="@color/colorAccent" />

Android는 사용자 정의 기본 아이콘을 표시합니다.

  • 알림 작성기 에서 보낸 모든 알림 메시지입니다.
  • 알림 페이로드에 아이콘을 명시적으로 설정하지 않은 알림 메시지입니다.

Android는 사용자 정의 기본 색상을 사용합니다.

  • 알림 작성기 에서 보낸 모든 알림 메시지입니다.
  • 알림 페이로드에 색상을 명시적으로 설정하지 않은 알림 메시지입니다.

사용자 지정 기본 아이콘이 설정되지 않고 알림 페이로드에 아이콘이 설정되지 않은 경우 Android는 흰색으로 렌더링된 애플리케이션 아이콘을 표시합니다.

onMessageReceived 재정의

FirebaseMessagingService.onMessageReceived 메서드를 재정의하여 수신된 RemoteMessage 객체를 기반으로 작업을 수행하고 메시지 데이터를 가져올 수 있습니다.

Java

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    // TODO(developer): Handle FCM messages here.
    // Not getting messages here? See why this may be: https://goo.gl/39bRNJ
    Log.d(TAG, "From: " + remoteMessage.getFrom());

    // Check if message contains a data payload.
    if (remoteMessage.getData().size() > 0) {
        Log.d(TAG, "Message data payload: " + remoteMessage.getData());

        if (/* Check if data needs to be processed by long running job */ true) {
            // For long-running tasks (10 seconds or more) use WorkManager.
            scheduleJob();
        } else {
            // Handle message within 10 seconds
            handleNow();
        }

    }

    // Check if message contains a notification payload.
    if (remoteMessage.getNotification() != null) {
        Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
    }

    // Also if you intend on generating your own notifications as a result of a received FCM
    // message, here is where that should be initiated. See sendNotification method below.
}

Kotlin+KTX

override fun onMessageReceived(remoteMessage: RemoteMessage) {
    // TODO(developer): Handle FCM messages here.
    // Not getting messages here? See why this may be: https://goo.gl/39bRNJ
    Log.d(TAG, "From: ${remoteMessage.from}")

    // Check if message contains a data payload.
    if (remoteMessage.data.isNotEmpty()) {
        Log.d(TAG, "Message data payload: ${remoteMessage.data}")

        if (/* Check if data needs to be processed by long running job */ true) {
            // For long-running tasks (10 seconds or more) use WorkManager.
            scheduleJob()
        } else {
            // Handle message within 10 seconds
            handleNow()
        }
    }

    // Check if message contains a notification payload.
    remoteMessage.notification?.let {
        Log.d(TAG, "Message Notification Body: ${it.body}")
    }

    // Also if you intend on generating your own notifications as a result of a received FCM
    // message, here is where that should be initiated. See sendNotification method below.
}

onDeletedMessages 재정의

경우에 따라 FCM이 메시지를 전달하지 못할 수 있습니다. 이는 연결 시점에 특정 기기의 앱에 대해 너무 많은 메시지(>100)가 보류 중이거나 기기가 한 달 이상 FCM에 연결되지 않은 경우 발생합니다. 이러한 경우 FirebaseMessagingService.onDeletedMessages() 에 대한 콜백을 수신할 수 있습니다. 앱 인스턴스가 이 콜백을 수신하면 앱 서버와 전체 동기화를 수행해야 합니다. 지난 4주 동안 해당 기기의 앱에 메시지를 보내지 않은 경우 FCM은 onDeletedMessages() 를 호출하지 않습니다.

백그라운드 앱에서 알림 메시지 처리

앱이 백그라운드에 있을 때 Android는 알림 메시지를 시스템 트레이로 보냅니다. 사용자가 알림을 탭하면 기본적으로 앱 런처가 열립니다.

여기에는 알림과 데이터 페이로드(및 알림 콘솔에서 보낸 모든 메시지)가 모두 포함된 메시지가 포함됩니다. 이러한 경우 알림은 장치의 시스템 트레이로 전달되고 데이터 페이로드는 런처 활동의 의도 외 추가로 전달됩니다.

앱으로의 메시지 전달에 대한 자세한 내용은 FCM 보고 대시보드 를 참조하십시오. FCM 보고 대시보드 에는 Android 앱의 "노출"(사용자가 본 알림)에 대한 데이터와 함께 Apple 및 Android 장치에서 보내고 열었던 메시지 수를 기록합니다.

백그라운드 제한된 앱(Android P 이상)

FCM은 사용자가 백그라운드 제한 을 설정한 앱에 메시지를 전달하지 않을 수 있습니다(예: 설정 -> 앱 및 알림 -> [앱 이름] -> 배터리). 앱이 백그라운드 제한에서 제거되면 이전과 같이 앱에 새 메시지가 전달됩니다. 메시지 손실 및 기타 백그라운드 제한 영향을 방지하려면 Android vitals 작업에 나열된 나쁜 동작을 피해야 합니다. 이러한 동작으로 인해 Android 기기에서 앱의 백그라운드가 제한됨을 사용자에게 추천할 수 있습니다. 앱은 isBackgroundRestricted() 를 사용하여 백그라운드 제한 여부를 확인할 수 있습니다.

전송 요청 작성

클라이언트 측의 주제에 대한 클라이언트 앱 인스턴스를 구독하거나 서버 API 를 통해 주제를 만든 후 주제에 메시지를 보낼 수 있습니다. FCM에 대한 전송 요청을 처음 구축하는 경우 중요한 배경 및 설정 정보는 서버 환경 및 FCM 에 대한 가이드를 참조하십시오.

백엔드의 전송 로직에서 다음과 같이 원하는 주제 이름을 지정합니다.

노드.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);
  });

자바

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

씨#

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

주제 조합 으로 메시지를 보내려면 대상 주제를 지정하는 부울 표현식인 조건 을 지정하십시오. 예를 들어 다음 조건은 TopicATopicB 또는 TopicC 를 구독하는 장치에 메시지를 보냅니다.

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

FCM은 먼저 괄호 안의 조건을 평가한 다음 왼쪽에서 오른쪽으로 표현식을 평가합니다. 위 식에서 단일 주제를 구독한 사용자는 메시지를 받지 않습니다. 마찬가지로, TopicA 를 구독하지 않은 사용자는 메시지를 수신하지 않습니다. 다음 조합은 수신합니다.

  • TopicATopicB
  • TopicATopicC

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

조건으로 보내려면:

노드.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);
  });

자바

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

씨#

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

다음 단계