최근 마케팅 팀 요청으로 세분화된 타겟 푸시 기능을 개발하던 중, 운영 환경 로그에서 java.lang.IllegalArgumentException: Invalid topic name 예외가 쏟아지는 현상을 목격했습니다. 원인은 간단했습니다. 마케팅 대시보드에서 입력한 토픽 이름이 '긴급공지'였기 때문입니다. FCM(Firebase Cloud Messaging)은 토픽 이름에 한글을 허용하지 않습니다. 이 글에서는 별도의 매핑 테이블(DB) 관리 없이, 표준 인코딩 기술만으로 이 제약을 우회하여 운영 효율을 극대화한 경험을 공유합니다.
Regex 제약 분석과 우회 전략
문제의 핵심은 FCM이 정의한 토픽 네이밍 규칙에 있습니다. 공식 문서를 뜯어보면 토픽 이름은 다음 정규 표현식을 만족해야 합니다.
[a-zA-Z0-9-_.~%]
이 규칙에 따르면 한글, 공백, 특수문자 대부분이 차단됩니다. 보통 개발자들은 이를 해결하기 위해 두 가지 방법을 사용합니다.
- 로마자 표기: '뉴스' → 'news', '공지' → 'notice'
- 매핑 테이블: DB에
ID: 101, Name: "이벤트"를 저장하고 토픽을 'topic_101'로 구독.
하지만 1번은 가독성이 떨어지고, 2번은 관리 포인트가 늘어납니다. 여기서 주목할 점은 정규식 마지막에 허용된 퍼센트 기호(%)입니다. 웹 표준 기술인 URL Encoding(Percent Encoding)을 사용하면 한글을 %로 시작하는 문자열로 변환할 수 있습니다. 즉, FCM의 제약을 위반하지 않으면서 한글의 의미를 유지할 수 있는 유일한 통로입니다.
The Solution: Encoding Pipeline
해결책은 클라이언트(구독)와 서버(발송) 양쪽에서 토픽 이름을 인코딩/디코딩하는 파이프라인을 구축하는 것입니다. 아래는 Android 클라이언트와 Java 백엔드에서의 구현 예시입니다.
UTF-8 기반의 URL 인코딩 함수를 사용하면 플랫폼 간 호환성 문제가 없습니다.
// [Android Client] Topic 구독 로직
import java.net.URLEncoder
import java.nio.charset.StandardCharsets
import com.google.firebase.messaging.FirebaseMessaging
fun subscribeToKoreanTopic(rawTopic: String) {
try {
// 1. 한글을 UTF-8 URL 인코딩 변환
// 예: "뉴스" -> "%EB%89%B4%EC%8A%A4"
val encodedTopic = URLEncoder.encode(rawTopic, StandardCharsets.UTF_8.toString())
// 2. FCM 구독 요청
FirebaseMessaging.getInstance().subscribeToTopic(encodedTopic)
.addOnCompleteListener { task ->
if (task.isSuccessful) {
// 성공 로그
}
}
} catch (e: Exception) {
// 인코딩 실패 예외 처리
}
}
// [Backend Server] 메시지 발송 로직 (Java)
public void sendFCMMessage(String koreanTopic, String messageBody) {
try {
// 서버에서도 동일하게 인코딩하여 타겟 지정
String targetTopic = URLEncoder.encode(koreanTopic, StandardCharsets.UTF_8);
Message message = Message.builder()
.setTopic(targetTopic) // 인코딩된 토픽 사용
.putData("body", messageBody)
.build();
FirebaseMessaging.getInstance().send(message);
} catch (Exception e) {
log.error("FCM Send Error", e);
}
}
Performance & Strategy Comparison
URL 인코딩 방식이 기존의 매핑 방식보다 아키텍처 관점에서 얼마나 효율적인지 비교해 보았습니다.
| 비교 항목 | DB 매핑 방식 (Legacy) | URL 인코딩 방식 (Recommended) |
|---|---|---|
| 구현 복잡도 | High (별도 테이블, API 필요) | Low (유틸리티 함수 호출) |
| 데이터 일관성 | DB 동기화 문제 발생 가능 | Stateless (변환 로직만 존재) |
| 디버깅 용이성 | ID(1042)만 보고 내용 파악 불가 | 디코딩 시 즉시 원문 확인 가능 |
| 운영 비용 | DB 조회 비용 발생 | CPU 연산 비용 미미함 |
Conclusion
FCM의 정규식 제약 때문에 한글 토픽을 포기하거나 복잡한 매핑 테이블을 만드는 것은 오버엔지니어링입니다. % 문자가 허용된다는 점을 이용해 URL 인코딩을 적용하면, 개발 생산성을 유지하면서도 운영팀이 원하는 직관적인 한글 키워드를 그대로 사용할 수 있습니다. 지금 바로 프로젝트의 레거시 코드를 확인해 보세요. 불필요한 매핑 로직을 걷어낼 기회일지도 모릅니다.
하진짜 제 영웅이십니다 FCM 한글꺠짐때문에 얼마나 고생헀는지 모릅니다 ㅠㅠ 감사합니다
ReplyDelete