토픽 구독은 Firebase Cloud Messaging의 메커니즘으로, 관심사에 따라 기기를 그룹화하고 구독자 전체 카테고리에 알림을 보낼 수 있습니다. 수천 개의 개별 Registration Token에 보내는 대신 토픽에 하나의 메시지만 보내면 됩니다. Firebase, 2025에 따르면, 토픽 구독은 뉴스 앱, 스포츠 중계 및 마케팅 캠페인에서 대규모 알림 전달에 사용됩니다.
주요 포인트
토픽 구독은 기기가 명명된 채널(토픽)을 구독하고 해당 채널로 전송된 메시지를 수신하는 그룹 푸시 알림 전달 메커니즘입니다. 각 토픽은 news_sports 또는 weather_alerts와 같은 문자열 이름으로 식별됩니다.
기기가 토픽을 구독하면 FCM은 해당 토픽의 수신자 목록에 Registration Token을 추가합니다. 토픽에 메시지가 전송되면 FCM은 자동으로 구독 중인 각 기기에 복사본을 라우팅합니다. Firebase는 기기당 구독 수를 제한하지 않습니다 — 앱은 사용자를 동시에 수십 개의 토픽에 구독시킬 수 있습니다.
토픽의 주요 장점은 확장성입니다. 백만 사용자에게 알림을 보내려면 토픽 이름과 함께 FCM에 하나의 HTTP 요청만 필요합니다. 개별 전송의 경우 백만 개의 요청 또는 한 번에 최대 500개 토큰의 배치 전송이 필요합니다. 토픽은 서버 측 로직도 단순화합니다 — 각 카테고리에 대해 토큰 목록을 저장할 필요가 없습니다.
| 파라미터 | 개별 전송 | 토픽 구독 |
|---|---|---|
| 요청 수 | 토큰당 하나 또는 최대 500개 배치 | 토픽당 하나 |
| 구독 관리 | 서버에서 (토큰 목록) | 클라이언트 또는 서버에서 |
| 동적 그룹 | 목록 업데이트 필요 | 구독을 통해 자동 |
| 수신자 제한 | 요청당 최대 500개 | 무제한 |
토픽 구독은 뉴스 앱에서 콘텐츠 분류에 널리 사용됩니다 — “스포츠”, “정치”, “기술” 토픽을 구독하면 관련 알림을 전달할 수 있습니다. 전자상거래에서는 특정 제품 카테고리의 할인에 대한 알림에 토픽이 사용됩니다. 메신저와 소셜 네트워크에서는 그룹 내 이벤트에 대한 알림에 토픽이 사용됩니다.
Firebase는 토픽 작업에 제한을 둡니다. 하나의 앱은 최대 2000개의 토픽을 가질 수 있습니다. 각 기기는 최대 2000개의 토픽을 구독할 수 있습니다. 구독/구독 취소 작업의 빈도도 제한됩니다 — 프로젝트당 분당 최대 3000회 작업. 이러한 제한을 초과하면 일시적으로 차단됩니다. 많은 수의 토픽이 있는 프로젝트의 경우 토픽 대신 조건(condition)을 사용하는 것이 좋습니다 — FCM은 타겟팅을 위한 논리 표현식을 지원합니다.
토픽 구독 프로세스는 세 단계로 구성됩니다: 클라이언트에서 구독 초기화, FCM 인프라에 등록, 작업 확인. 구독이 성공하면 기기는 해당 토픽으로 전송된 메시지 수신을 시작합니다.
클라이언트가 subscribeToTopic() 메서드를 호출하면 Firebase SDK가 FCM 서버에 요청을 보냅니다. 서버는 작업의 유효성을 확인하고 기기 토큰을 토픽의 구독자 목록에 추가합니다. FCM은 성공적인 구독 확인을 클라이언트에 반환합니다. 이 시점부터 이 토픽에 대한 모든 메시지가 기기에 전달됩니다.
Firebase 콘솔에서 미리 토픽을 생성할 필요가 없습니다. 첫 번째 기기가 news_promo라는 이름의 토픽을 구독하면 FCM이 자동으로 생성합니다. 마지막 기기가 구독을 취소해도 토픽은 시스템에 비활성 상태로 남아 있으며, 새 구독이 발생하면 다시 작동을 시작합니다.
Android에서는 FirebaseMessaging SDK를 통해 토픽 구독 및 구독 취소가 수행됩니다. subscribeToTopic() 및 unsubscribeFromTopic() 메서드는 매개변수로 토픽 이름을 받습니다. 작업은 비동기식이며 결과 처리가 필요합니다.
구독하려면 대상 토픽 이름으로 subscribeToTopic()을 호출하기만 하면 됩니다. Firebase SDK는 네트워크 요청과 실패 시 재시도를 자동으로 관리합니다. Registration Token을 성공적으로 획득한 후 토픽을 구독하는 것이 좋습니다.
class TopicSubscriber(private val context: Context) {
fun subscribeToNewsTopic() {
FirebaseMessaging.getInstance()
.subscribeToTopic("news_latest")
.addOnCompleteListener { task ->
val msg = if (task.isSuccessful) {
"Subscribed to news topic"
} else {
"Subscription failed"
}
Log.d("FCM", msg)
}
}
fun unsubscribeFromNewsTopic() {
FirebaseMessaging.getInstance()
.unsubscribeFromTopic("news_latest")
.addOnCompleteListener { task ->
Log.d("FCM", "구독 취소됨: ${task.isSuccessful}")
}
}
}
실제 앱에서 사용자는 여러 카테고리를 구독할 수 있습니다. 편리한 관리를 위해 서버 측과 구독 상태를 동기화하는 관리자 클래스를 만드세요. 사용자가 로그인하면 프로필에서 구독을 복원합니다.
class SubscriptionManager(private val context: Context) {
private val fcm = FirebaseMessaging.getInstance()
suspend fun syncSubscriptions(topics: List<String>) {
topics.forEach { topic ->
fcm.subscribeToTopic(topic).await()
}
}
suspend fun removeAllSubscriptions() {
val savedTopics = getSavedTopics()
savedTopics.forEach { topic ->
fcm.unsubscribeFromTopic(topic).await()
}
}
private fun getSavedTopics(): List<String> {
return listOf("news_latest", "promotions", "updates")
}
}
iOS에서는 토픽 구독 프로세스가 논리적으로 Android와 동일하지만 Swift Firebase Messaging API를 사용합니다. subscribe 및 unsubscribe 메서드는 Messaging 인스턴스에서 호출되며 비동기식입니다.
iOS 앱에서 토픽을 구독하려면 Messaging.subscribe() 메서드를 사용하세요. Firebase 초기화 및 Registration Token 획득 후 구독을 호출하는 것이 중요합니다. Apple은 토픽을 구독하기 전에 알림 권한을 요청할 것을 권장합니다.
import FirebaseMessaging
class PushTopicManager {
func subscribeToTopic(topic: String) {
Messaging.messaging().subscribe(toTopic: topic) { error in
if let error = error {
Log.e("FCM", "구독 오류: \(error)")
} else {
Log.d("FCM", "\(topic)에 구독됨")
}
}
}
func unsubscribeFromTopic(topic: String) {
Messaging.messaging().unsubscribe(fromTopic: topic) { error in
if let error = error {
Log.e("FCM", "구독 취소 오류: \(error)")
}
}
}
}
iOS에서 토픽 구독은 Firebase가 APNs에서 받는 Registration Token에도 연결됩니다. APNs 토큰이 변경되면(예: 기기 복원 후) Firebase는 자동으로 구독을 새 토큰으로 전송합니다. 그러나 드문 경우 Registration Token 업데이트 후 재구독이 필요할 수 있습니다.
서버 측 구독 관리를 통해 클라이언트 앱을 개입시키지 않고 기기를 구독 및 구독 취소할 수 있습니다. 이는 관리, A/B 테스트 및 백엔드에서 구독 관리에 유용합니다.
Firebase는 대량 구독 관리를 위한 REST API를 제공합니다. /v1/projects/{project_id}/subscriptions 엔드포인트는 단일 요청으로 최대 1000개 기기까지 구독할 수 있습니다. API는 식별을 위해 기기의 Registration Token을 사용합니다.
const admin = require("firebase-admin")
async function subscribeUsersToTopic(tokens, topic) {
try {
const response = await admin
.messaging()
.subscribeToTopic(tokens, topic)
Log.info(`Success: ${response.successCount}`)
Log.info(`Failures: ${response.failureCount}`)
} catch (error) {
Log.error("구독 오류", error)
}
}
서버 측 구독 관리는 여러 시나리오에서 사용됩니다. 사용자가 등록하면 서버가 자동으로 기본 토픽에 구독시킵니다. 웹 버전에서 기본 설정이 변경되면 서버가 모바일 기기의 구독을 동기화합니다. 관리자는 디버깅을 위해 테스트 기기를 내부 토픽에 구독시킬 수 있습니다. 대량 작업을 위해 FCM은 Instance Group 메서드를 제공하여 단일 그룹 식별자를 통해 기기 그룹의 구독을 관리할 수 있습니다.
Firebase는 기기의 현재 구독을 확인하기 위한 내장 API를 제공하지 않습니다. 개발자는 서버 측에서 자체 구독 데이터베이스를 유지 관리하는 것이 좋습니다. 각 앱 실행 시 클라이언트는 활성 토픽 목록을 전송하여 서버와 구독을 동기화합니다. 이는 동기화 불일치를 식별하고 필요한 경우 구독을 복원하는 데 도움이 됩니다. 감사를 위해 Firebase Cloud Functions 로그를 사용하세요 — 각 subscribe/unsubscribe 작업을 기록할 수 있습니다.
자주 묻는 질문
최대 토픽 수는 앱당 2000개입니다. 더 필요하면 기기 그룹 또는 토큰별 개별 전송을 고려하세요.
Firebase는 기기의 구독 목록을 가져오는 직접적인 API를 제공하지 않습니다. 개발자는 자체 서버에 구독 상태를 저장하고 클라이언트와 동기화하는 것이 좋습니다.
FCM이 성공 결과를 반환합니다. Firebase는 존재하지 않는 토픽의 구독 취소를 no-op 작업으로 처리합니다 — 오류가 발생하지 않으며 상태가 변경되지 않습니다.
네, Firebase 콘솔의 Cloud Messaging 섹션에서 토픽을 대상 audience로 선택하고 웹 인터페이스를 통해 테스트 또는 프로덕션 알림을 보낼 수 있습니다.
일반적으로 구독은 몇 초 내에 활성화됩니다. 그러나 드문 경우 FCM 서버 간 전파로 인해 지연이 30~60초까지 발생할 수 있습니다.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.