현재 일하는 곳에서 개발 중인 앱에 firebase를 통해 푸시 알림을 보내고 sms를 전송하는 부분이 있다. 관련된 부분을 수정을 해야하는 상황이라 fcm이 뭐고 어떤 방식으로 돌아가는지 알아볼 겸 글을 작성하게 됐다.
FCM이란?
구글에서 무료로 메시지를 안정적으로 전송할 수 있는 교차 플랫폼 메시징 솔루션
앱 서버에서 FCM 서버로 메시지 요청이 가고 이를 받은 FCM 서버가 클라이언트에게 메시지를 보낸다.
쉽게 말해 서비스 회사의 서버와 클라이언트 사이에 FCM 서버가 존재하는 거다.
그래 메시지 보내주는 거 알겠어,,근데 왜 이렇게 메시지를 보내는데? 뭐가 다른걸까
사용자 김씨에게 어떠한 메세지를 전달해야한다고 가정해보자.
김씨에게 메세지를 어떻게 전달할 수 있을까
서비스 회사의 서버에서 김씨에게 메세지를 보내면 된다.
문제는 김씨가 실시간으로 서버로 부터 메세지를 받으려면 서버에 계속 접속해 있어야 한다.
이러한 방식을 사용하면 배터리도 빨리 딣고 네트워크 사용에도 문제가 발생한다.
이때 FCM을 사용하면 문제를 해결할 수 있다.
중간에 FCM 서버가 끼므로 서비스 회사의 서버에 항상 접속해 있지 않아도 되기 때문이다.
서비스 프로그램이 실행 중이 아니더라도 리스너를 통해 메시지를 수신받을 수 있다.
FCM을 통한 메시지 전송 흐름(FE+BE)
1. 클라이언트에서 FCM 서버로부터 FCM 토큰을 요청하고 획득한다.
2. 클라이언트에서 서버한테 해당 토큰을 전달하고 서버는 전달 받은 토큰을 디비에 저장한다.
3. 서버가 전달 받은 토큰을 이용해 FCM 서버로 메시지 전송 요청을 보낸다.
4. 요청을 받은 FCM 서버가 사용자에게 메시지를 전송한다.
5. 사용자가 사용 중인 서비스에서 리스너를 통해 메시지를 받는다.
FCM 토큰 만료 케이스
FCM 토큰은 만료되지 않으나, 다음과 같은 특정 케이스들에선 변경된다.
1. 앱 instance ID 삭제
2. 앱 삭제 혹은 재설치
3. 앱 사용자가 앱 데이터 삭제
FCM 라이브러리 추가(BE, build.gradle)
dependencies {
...
implementation 'com.google.firebase:firebase-messaging:21.1.0'
}
FCM 메시지 종류 2가지
1. notification message
title과 body로 구성
fcm SDK에서 자동으로 처리
{
"message":{
"token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"notification":{
"title":"Portugal vs. Denmark",
"body":"great match!"
}
}
}
2. data message
key-value 쌍으로 구성
클라이언트 앱에서 처리
{
"message":{
"token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"data":{
"Nick" : "Mario",
"body" : "great match!",
"Room" : "PortugalVSDenmark"
}
}
}
FCM 서버 메시지 요청 방법 4가지
1. Firebase Admin SDK 이용(원시 프로토콜)
Node.js, 자바, Python, C#, Go 지원
2. HTTP V1 API 이용
가장 최신 프로토콜, firebase admin sdk는 이 프로토콜을 기반으로
대부분의 사례에 이 API 사용 추천
3. 기존 HTTP API 이용
4. XMPP 서버
전송하는 각 메시지를 고유하게 구별하기 위해 서버에서 메시지 ID를 생성할 수 있어야 함
참고 사이트
https://firebase.google.com/docs/cloud-messaging/
https://developer88.tistory.com/159
https://team-platform.tistory.com/23
'Spring > 개인 공부' 카테고리의 다른 글
[아임포트/spirng boot] 다날 SMS 본인인증 페이지 띄우기+access 토큰 전달 API 개발하기 (3) | 2022.05.28 |
---|---|
[Spring] @Scheduled 어노테이션을 활용한 스케줄링 (0) | 2022.05.08 |
[Spring] Jackson 직렬화 Annotation 정리 (0) | 2022.04.09 |
[Data JPA] 페이징 처리 aka pagination, sorting, pageable (0) | 2022.03.31 |
[EC2 프리티어] RAM 부족할 때 swap memory로 메모리 늘려서 해결하기 (0) | 2022.02.11 |