Spring/FCM

FCM 소개 및 Spring 프로젝트에서 구현

ch-yang 2023. 4. 24. 20:16

FCM 소개

Firebase Cloud Messaging (FCM)은 Google이 제공하는 클라우드 메시징 서비스로 애플리케이션 서버에서 클라이언트 앱(안드로이드, IOS, Web Browser)로 알림 메시지나 데이터 메시지를 전송할 수 있습니다.

FCM 아키텍처

FCM 문서 - FCM 아키텍처 개요

  • 애플리케이션 서버
    메시지 생성하고 대상을 타겟팅하여 FCM 백엔드로 전송합니다. 일반적으로 개발자가 구축하는 백엔드 서버를 의미합니다.
  • FCM 서버
    구글이 제공하는 클라우드 서비스로 애플리케이션 서버나 Firebase Console로부터 메시지를 받아, 대상 기기나 사용자에게 메시지를 라우팅합니다.
  • 플랫폼 수준 전송 레이어
    각 플랫폼 (안드로이드, IOS, Web)에 특화된 메시지 전송 방식을 사용하여, FCM 서버로부터 받은 메시지를 클라이언트 앱에 전달합니다.
  • 클라이언트 앱
    FCM 서버로부터 메시지를 수신하고, 애플리케이션 로직에 따라 알림을 표시하거나 메시지를 처리합니다.

FCM 메시지 전송 프로세스

  1. 클라이언트 앱이 최초로 실행되거나 재발급이 필요한 경우, FCM 서버에 기기를 등록하고 앱과 기기에 대해 고유한 등록 토큰을 받습니다.
  2. 클라이언트 앱은 발급받은 등록 토큰을 애플리케이션 서버에 전송하고, 애플리케이션 서버는 토큰을 저장합니다. 이 과정에서 애플리케이션 서버는 해당 기기를 식별할 수 있는 토큰을 확보합니다.
  3. 애플리케이션 서버는 필요에 따라 FCM 서버에 메시지 전송을 요청합니다. 이때, 등록 토큰이나 토픽 이름을 이용해서 메시지 수신 대상을 지정합니다.
  4. FCM 서버는 애플리케이션 서버의 요청을 처리해서 지정된 기기의 클라이언트 앱에 전송합니다.

메시지 유형

FCM 메시지 유형에는 아래 두 가지 유형이 있습니다.

1. 알림 메시지(Notification)
클라이언트 앱에서 알림을 표시하기 위해 사용됩니다. 앱이 포그라운드에서 실행 중이면 앱의 코드에 따라 동작이 결정되고, 백그라운드 상태에서는 FCM SDK가 앱을 대신해서 기기에 메시지를 표시합니다. 사전 정의된 키-값 쌍의 페이로드를 포함하고 선택적으로 Data 페이로드가 포함 될 수도 있습니다.


  
{
"message":{
"token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"notification":{
"title":"Portugal vs. Denmark",
"body":"great match!"
}
}
}

2. 데이터 메시지(Data)
포그라운드 및 백그라운드 상태에 관계없이 클라이언트 앱 개발자가 작성한 코드에 따라 메시지를 처리합니다. Notification의 페이로드와 달리 커스텀한 키-값 쌍의 Data 페이로드를 포함합니다.


  
{
"message":{
"token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"data":{
"Nick" : "Mario",
"body" : "great match!",
"Room" : "PortugalVSDenmark"
}
}

Topic

토픽은 기기 토큰을 그룹화하는 기능입니다. 토픽을 사용하면 개별 기기 토큰 대신 토픽 이름으로 메시지를 전송할 수 있습니다.


  
// Java에서 "news" 토픽 구독하는 예시
FirebaseMessaging.getInstance().subscribeToTopic("news");
// 토픽을 사용하는 JSON 예시
{
"message":{
"topic":"subscriber-updates",
"notification":{
"body" : "This week's edition is now available.",
"title" : "NewsMagazine.com",
},
"data" : {
"volume" : "3.21.15",
"contents" : "http://www.news-magazine.com/world-week/21659772"
},
"android":{
"priority":"normal"
},
"apns":{
"headers":{
"apns-priority":"5"
}
},
"webpush": {
"headers": {
"Urgency": "high"
}
}
}
}

애플리케이션 서버에서 FCM 기능 구축

FCM 서버와 상호작용하는 애플리케이션 서버를 구축하는 방법에는 Firebase Admin SDK를 사용하는 방법과 HT 프로토콜을 사용하는 방법이 있습니다. 자주 사용되는 프로그래밍 언어를 지원하고, 인증 및 승인 처리가 편리한 Firebase Admin SDK를 사용하는 것을 추천합니다.

선택할 수 있는 옵션은 다음 4가지 방법이 있습니다.

  1. Firebase Admin SDK
  2. FCM HTTP v1 API
  3. 기존 HTTP 프로토콜
  4. 기존 XMPP 서버 프로토콜

2~3 번 옵션을 사용하는 방법은 최신 기능, 성능, 보안 등의 업데이트 지원을 하지 않고 있기 때문에 새 프로젝트에서 선택하는 것은 권장되지 않습니다. 

Firebase Admin SDK 사용

참고

1. 의존성 추가


  
// gradle
dependencies {
implementation 'com.google.firebase:firebase-admin:9.1.1'
}

2. 초기화

Firebase Admin SDK 초기화에는 서비스 계정 키가 포함된 json 파일이 필요합니다. 얻는 방법은 생략하겠습니다.


  
public class FcmInitializer {
@Value("${fcm.certification-file}")
private String fcmCertificationFile;
@PostConstruct
public void initialize() throws IOException {
ClassPathResource serviceAccount = new ClassPathResource(fcmCertificationFile);
FirebaseOptions options = FirebaseOptions.builder()
.setCredentials(GoogleCredentials.fromStream(serviceAccount.getInputStream()))
.build();
if (FirebaseApp.getApps().isEmpty()) {
FirebaseApp.initializeApp(options);
log.info("Firebase application has been initialized");
}
}
}

이 코드는 수정할 부분이 있습니다.

@Value("${fcm.certification-file}")은 인증과 권한을 위한 서비스 계정 키가 포함된 json 파일의 경로를 반환하는데 공식 문서에서는 파일의 경로를 환경 변수 "GOOGLE_APPLICATION_CREDENTIALS"에서 지시하는 것을 권장합니다.


  
// windows
$ env:GOOGLE_APPLICATION_CREDENTIALS="C:\Users\username\Downloads\service-account-file.json"
// linux 혹은 macOS
export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/service-account-file.json"

최종적으로 수정 될 코드입니다.


  
FirebaseOptions options = FirebaseOptions.builder()
.setCredentials(GoogleCredentials.getApplicationDefault())
.build();
FirebaseApp.initializeApp(options);

그 외에 여러 앱을 초기화하는 방법도 있는데 참고 링크만 남겼습니다.

메시지 전송

메시지 전송방법은 공식 사이트의 테스트 코드가 잘 작성되어있어 생략하고 링크로 대체합니다.

https://github.com/firebase/firebase-admin-java/blob/master/src/test/java/com/google/firebase/snippets/FirebaseMessagingSnippets.java

 

GitHub - firebase/firebase-admin-java: Firebase Admin Java SDK

Firebase Admin Java SDK. Contribute to firebase/firebase-admin-java development by creating an account on GitHub.

github.com