본 문서는 FCM(Firebase 클라우드 메시징) 프로토콜 변경으로 당사 제품의 업데이트에 필요한 내용을 가이드 합니다.
FCM(Firebase 클라우드 메시징) 서비스는 2024년 6월 20일을 기점으로 레거시(XMPP, HTTP) 방식의 통신 API를 중단하고, 새로운 HTTP v1 API를 지원합니다.
¶ HTTP v1 API 사용시 장점
액세스 토큰을 통한 보안 향상: HTTP v1 API는 OAuth2 보안 모델에 따라 수명이 짧은 액세스 토큰을 사용합니다. 액세스 토큰이 공개되는 경우에도 악의적으로 사용될 수 있는 시간은 만료되기 전 1시간 정도뿐입니다. 갱신 토큰이 기존 API에서 사용하는 보안 키만큼 자주 전송되지 않으므로 캡처될 가능성이 매우 낮습니다.
보다 효율적인 플랫폼에 따른 메시지 맞춤설정: 메시지 본문의 경우 HTTP v1 API는 모든 대상 인스턴스에 전달되는 공용 키는 물론 플랫폼에 따라 메시지를 맞춤설정할 수 있는 플랫폼별 키가 있습니다. 이러한 키를 사용하면 메시지 하나로 여러 클라이언트 플랫폼에 약간 다른 페이로드를 전송하는 '재정의'를 만들 수 있습니다.
새 클라이언트 플랫폼 버전을 위한 확장성 강화 및 미래 경쟁력 확보: HTTP v1 API는 Apple 플랫폼, Android, 웹에 제공되는 메시지 옵션을 완전히 지원합니다. 플랫폼별로 JSON 페이로드에 자체 정의된 블록이 있으므로 FCM에서 필요에 따라 새 버전과 새 플랫폼으로 API를 확장할 수 있습니다.
HTTP v1 전송 요청의 경우, 기존 요청에서 사용하는 서버 키 문자열 대신 OAuth 2.0 액세스 토큰이 필요합니다.
액세스 토큰을 얻기 위해서는 Firebase 프로젝트의 서비스 계정의 비공개 키 파일(JSON)이 필요합니다.
프로젝트 설정 > 클라우드 메시징 탭에서 Firebase Cloud Messaging API(V1)
의 사용 여부 상태를 확인합니다.
1.1.3 항목으로 넘어갑니다.
더보기(⋮)
메뉴를 통해 API 콘솔에 접속하여 사용
으로 상태를 변경합니다.
정상적으로 발급이 완료되었다면 아래와 같은 형식의
JSON
파일이 다운로드 됩니다.
{
"type": "service_account",
"project_id": "...",
"private_key_id": "...",
"private_key": "-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----\n",
"client_email": "...",
"client_id": "...",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/...gserviceaccount.com",
"universe_domain": "googleapis.com"
}
발급 받으신 파일(JSON)은 당사 엔지니어가 PROVIDER 패치 작업에 사용할 수 있도록 Push 서버에 반입하여 주시기 바랍니다.
직접 패치 작업을 진행하시는 경우, 제품 패치 가이드를 참고하어 진행하시기 바랍니다.
아래 구글 공식 가이드라인 문서에 의거하여, 모든 IP에 대하여 443 포트 접속 허용을 권장드립니다.
접속 도메인 접속을 제한하는 네트워크 환경의 경우, 다음의 도메인에 대해 접속 허용이 추가로 필요합니다.
아래의 '구글 공식 FCM 방화벽 가이드 라인'은 참고하시되, 다음의 내용은 반드시 확인하시기 바랍니다. 현재 구글 공식 가이드 라인은 모든 내용을 포괄하고 있지 않습니다. 특히, 새롭게 도입된 프로토콜(HTTP v1)은 OAuth2 액세스 토큰을 활용하므로, 구글 OAuth2 관련 방화벽 룰셋 항목 추가가 필요합니다. 또한, 1.2.1 항목에서 언급한 도메인 목록에 대한 접근 허용이 필수적입니다. 이 점을 유념하시어 방화벽 룰셋 등록에 착오 없으시길 바랍니다.
¶ 구글 공식 FCM 방화벽 가이드 라인
조직에 인터넷 트래픽 송수신을 제한하는 방화벽이 있으면 모바일 기기에서 FCM을 사용하여 연결할 수 있도록 방화벽을 구성해야 네트워크의 기기에서 메시지를 수신할 수 있습니다. FCM은 대개 포트 5228을 사용하지만 443, 5229, 5230을 사용하는 경우도 있습니다.
네트워크에 연결된 기기의 경우 IP 범위가 매우 자주 변경되며 개발자의 방화벽 규칙이 오래되면 사용자 환경에 영향을 줄 수 있으므로 FCM에서 특정 IP를 제공하지 않습니다. IP 제한 없이 포트 5228~5230,443을 허용하는 것이 가장 좋습니다. 하지만 IP 제한이 있어야 한다면 goog.json에 나와 있는 모든 IP 주소를 허용해야 합니다. 이 긴 목록은 정기적으로 업데이트되며 규칙을 월 단위로 업데이트하는 것이 좋습니다. 방화벽 IP 제한으로 인해 발생하는 문제는 보통 간헐적이며 진단하기 어렵습니다.
Google에서는 IP 주소 대신 허용 목록에 포함될 수 있는 도메인 이름 집합을 제공합니다. 이러한 호스트 이름은 아래에 나와 있습니다. 추가 호스트 이름을 사용하기 시작하면 여기에 목록이 업데이트됩니다. 방화벽 규칙에 도메인 이름을 사용하면 방화벽 기기에서 작동하거나 작동하지 않을 수 있습니다.
- 출처: https://firebase.google.com/docs/cloud-messaging/concept-options?hl=ko#messaging-ports-and-your-firewall
- 해당 가이드 라인의 방화벽 포트 정보는 클라이언트와 서버를 포함한 포트 정보입니다. Provider와 구글 서버 통신의 경우 443 포트만 접속이 허용되면 됩니다.
신규 버전의 Provider 데몬은 Java 1.8+
환경에서 구동 가능하며, 하위 버전인 경우 적합한 Java 버전의 설치가 필요합니다.
신규로 Java가 설치되는 경우, Java 설치 경로를 당사 엔지니어에게 전달해주시기 바랍니다.
본 패치 가이드는 모피어스 Push - Provider 4.0 ~ 5.5 버전의 패치 방법에 대해 기술합니다.
상기 버전에 해당되지 않는 경우, 당사 기술지원사이트를 통해 문의바랍니다.
/{Provider 배포 경로}/stop.sh
파일을 실행합니다.
기존 설치 디렉토리 전체를 백업하신 후 작업하시는 것을 권장드립니다. (로그파일 제외)
아래의 디렉토리 및 파일에 대하여 교체합니다.
# 제품 및 라이브러리 경로
/{Provider 배포 경로}/target/**
# 제품 관련 실행 스크립트 파일 경로
/{Provider 배포 경로}/start.cmd (Windows OS만 해당/서비스 방식인 경우, 별도 문의)
/{Provider 배포 경로}/start.sh (Linux/Unix OS만 해당)
/{Provider 배포 경로}/stop.sh (Linux/Unix OS만 해당)
/{Provider 배포 경로}/conf/config.properties
파일을 열어 아래 옵션 값을 추가 및 수정합니다.
Provider 4.0 인 경우
################################################
# 추가 되는 설정
################################################
GCM_TOKEN_SRC1={FCM 서비스 비공개 키 json 파일 경로}
# GCM 발송 타임아웃(기본값 200 / 단위 ms)
GCM_SEND_TIMEOUT=200
# GCM 발송 풀 크기(기본값 70 / 단위 개수)
GCM_SEND_POOL_SIZE=70
# GCM HTTP KeepAlive 유지시간(기본값 3 / 단위 분)
GCM_SEND_KEEPALIVE_TTL=3
# GCM HTTP 접속 유지시간(기본값 10 / 단위 분)
GCM_SEND_CONNECTION_TTL=10
# GCM HTTP 발송 쓰레드 수(기본값 50 / 단위 개수)
GCM_SEND_THREAD_CNT=50
################################################
# 수정 되는 설정
################################################
# 워커스레드 개수를 기본 10을 50으로 조정
WORKTHREAD_CNT = 50
Provider 5.0/5.5 기준
################################################
# 추가 되는 설정
################################################
GCM_TOKEN_SRC1={FCM 서비스 비공개 키 json 파일 경로}
# GCM 발송 타임아웃(기본값 200 / 단위 ms)
GCM_SEND_TIMEOUT=200
# GCM 발송 풀 크기(기본값 70 / 단위 개수)
GCM_SEND_POOL_SIZE=70
# GCM HTTP KeepAlive 유지시간(기본값 3 / 단위 분)
GCM_SEND_KEEPALIVE_TTL=3
# GCM HTTP 접속 유지시간(기본값 10 / 단위 분)
GCM_SEND_CONNECTION_TTL=10
# GCM HTTP 발송 쓰레드 수(기본값 50 / 단위 개수)
GCM_SEND_THREAD_CNT=50
################################################
# 수정 되는 설정
################################################
# 워커스레드 개수를 기본 10을 50으로 조정
WORKTHREAD_CNT = 50
GCM_USE_PROTOCOL는 더 이상 유효한 설정이 아님
Provider 5.1 기준
################################################
# 추가 되는 설정
################################################
FCM_TOKEN_SRC1={FCM 서비스 비공개 키 json 파일 경로}
# FCM 발송 타임아웃(기본값 200 / 단위 ms)
FCM_SEND_TIMEOUT=200
# FCM 발송 풀 크기(기본값 70 / 단위 개수)
FCM_SEND_POOL_SIZE=70
# FCM HTTP KeepAlive 유지시간(기본값 3 / 단위 분)
FCM_SEND_KEEPALIVE_TTL=3
# FCM HTTP 접속 유지시간(기본값 10 / 단위 분)
FCM_SEND_CONNECTION_TTL=10
# FCM HTTP 발송 쓰레드 수(기본값 50 / 단위 개수)
FCM_SEND_THREAD_CNT=50
################################################
# 수정 되는 설정
################################################
# 워커스레드 개수를 기본 10을 50으로 조정
WORKTHREAD_CNT = 50
FCM_USE_PROTOCOL는 더 이상 유효한 설정이 아님
/{Provider 배포 경로}/conf/logback.xml
파일을 열어 아래 옵션 값을 추가합니다.
################################################
# 추가 되는 설정
################################################
<logger name="com.google.firebase" additivity="false">
<level value="INFO"/>
<appender-ref ref="SERVER"/>
</logger>
<logger name="org.apache.http" additivity="false">
<level value="INFO"/>
<appender-ref ref="SERVER"/>
</logger>
Java
설치 디렉토리가 변경된 경우, 기동 스크립트(start.sh
,start.cmd
)의 수정이 필요하며, 일반적으로 기동 스크립트 내의JAVA_HOME
변수를 통해 설정하고 있습니다.
기동 스크립트의 위치는 일반적으로 아래와 같습니다, 해당 파일을 실행시켜 Provider를 기동합니다.
/{Provider 배포 경로}/start.sh
/{Provider 배포 경로}/start.cmd
패치 작업의 정상 완료 여부 확인을 위해 아래의 항목을 테스트하시기 바랍니다.
Push 4.0 ~ 5.0 및 5.5 버전
고객사 비즈니스 로직 포함한 메시지 수신 테스트 (EXT 파라미터 포함 권장)
UPNS 사용시, DOZ_GCM_SEND 파라미터 발송을 통한 FCM 더미 메시지 수신 확인 (Android Studio를 통한 확인 권장)
Push 5.1 버전
고객사 비즈니스 로직 포함한 메시지 수신 테스트 (EXT 파라미터 포함 권장)
UPNS 사용시, DOZ_FCM_SEND 파라미터 발송을 통한 FCM 더미 메시지 수신 확인 (Android Studio를 통한 확인 권장)
배치 발송 테스트 - 우선순위 파라미터(PRIORITY)를 1 설정
실시간 발송 테스트 - 우선순위 파라미터(PRIORITY)를 3 설정
로그에서 다음과 같은 형식의 로그가 출력됩니다.
15:52:04.084 [main] ERROR com.mium.server.PublicSenderServer - ./conf/[FCM_CERT].json 파일이 존재하지 않습니다.
config.properties 설정 파일의 FCM_TOKEN_SRC? 또는 GCM_TOKEN_SRC?에 설정된 경로에 파일이 존재하는지 확인하시기 바랍니다.
로그에서 다음과 같은 형식의 로그가 출력됩니다.
15:54:57.194 [main] ERROR com.mium.server.PublicSenderServer - ./conf/[FCM_CERT].json 파일이 JSON 형식이 아닙니다.
com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Expected ':' at line 2 column 4 path $.
at com.google.gson.Gson.fromJson(Gson.java:978)
at com.google.gson.Gson.fromJson(Gson.java:901)
at com.mium.server.PublicSenderServer.getGcmTokenMap(PublicSenderServer.java:431)
at com.mium.server.PublicSenderServer.init(PublicSenderServer.java:213)
at com.mium.server.PublicSenderServer.main(PublicSenderServer.java:552)
... 중략 ...
FCM JSON 인증서는 JSON Text 형식의 파일입니다. 인증서 파일이 올바른지 확인하시기 바랍니다.
일반적으로 다음의 상황에서 발생합니다.
14:11:31.485 [GCMCallback-0] WARN com.mium.server.gcm.GCMSender - !!![FCM HTTP v1 => PROVIDER] FAIL : UNKNOWN(알 수 없는 오류), CUID : test1 (SEQNO : 48, PSID : [FCM TOKEN]), Exception Message : Unknown error while making a remote service call: Error getting access token for service account: Connection refused (Connection refused), iss: mock-project-id-owner@mock-project-id.iam.gserviceaccount.com
13:24:03.899 [GCMCallback-0] ERROR com.mium.server.gcm.GCMSender - Cause: com.google.auth.oauth2.GoogleAuthException: Error getting access token for service account: Connection refused (Connection refused), iss: firebase-adminsdk-rgmdn@project-id.iam.gserviceaccount.com | Message: Unknown error while making a remote service call: Error getting access token for service account: Connection refused (Connection refused), iss: firebase-adminsdk-rgmdn@project-id.iam.gserviceaccount.com
com.google.firebase.messaging.FirebaseMessagingException: Unknown error while making a remote service call: Error getting access token for service account: Connection refused (Connection refused), iss: firebase-adminsdk-rgmdn@project-id.iam.gserviceaccount.com
at com.google.firebase.messaging.FirebaseMessagingException.withMessagingErrorCode(FirebaseMessagingException.java:51)
at com.google.firebase.messaging.FirebaseMessagingClientImpl$MessagingErrorHandler.createException(FirebaseMessagingClientImpl.java:293)
... 중략 ...
일반적으로 다음의 상황에서 발생합니다.
일반적으로 앱을 업데이트 하지 않아도, 정상 동작함 (이유 : 서버 end-point 변경 )
확인 사항
- 수신 확인 : 서버 패치 후, 클라이언트에서 정상적인 수신이 되는지 체크
- 수신이 되지 않은 경우 : FCM SDK 버전 변경
- iOS는 해당 없음 (이유 : APNS 이용)
안드로이드 FCM SDK version 23.1.2 이상