FCM이란?
- 플랫폼에 종속되지 않고 푸시 메시지를 전송할 수 있는 교차 플랫폼 메시징 솔루션
- Firebase Cloud Messaging
왜 사용할까?
- 플랫폼에 종속되지 않는다.
- 플랫폼 환경별로 개발해야하는 불현함을 해소한다.
- Android : GCM (Google Cloud Messaging)
- iOS : APNS (Apple Push Notification service)
- 사용되는 리소스가 감소한다.
- 실시간으로 푸시 메시지를 받으려면 사용자는 항상 서버에 접속해있어야 한다.
- 이는 사용자 기기의 배터리 및 네트워크 리소스를 크게 낭비한다.
- 클라우드 메시징 서버를 중간다리로 둔다면 낮은 배터리와 네트워크 리소스만 사용해도 된다.
- 실시간으로 푸시 메시지를 받으려면 사용자는 항상 서버에 접속해있어야 한다.
환경설정
의존성 추가
FirebaseApp에 대한 인스턴스 생성
- 만약에 패키징이 WAR인 경우에는 Resource 클래스를 통해 파일 정보를 불러들여도 된다.
- 다만 패키징이 JAR일 경우에는 경로 문제로 인하여 ResourceLoader를 통해 파일 정보를 불러들여야 한다.
데이터를 처리할 객체
- 데이터를 처리하기 위한 객체를 생성한다.
- 푸시를 보내는 다양한 방법이 있어서 파라미터도 많아져야 하지만
간단하게만 보낼꺼면 처리용 객체도 간단하게 만들면 된다.
메시지 가공하기
- ADMIN SDK를 통해 메시지를 전달할 때는 다양한 객체를 사용한다.
- 그 중에서 많이 쓰이는 건 Message와 Notification이다.
- Message와 Notification은 com.google.firebase.messaging 패키지에 포함되어 있다.
- 디테일하게 사용하고 싶을 때는 직접 소스를 까서 확인하도록 하고 지금은 간단하게만 알아보자.
- setTitle
- 제목을 설정한다.
- setBody
- 내용을 설정한다.
- setToken
- 토큰을 설정한다.
- 토큰은 Firebase에서 각 기기에 대해서 고유하게 발급하는 고유값을 의미한다.
- Firebase는 토큰을 통해 각 기기에 메시지를 발송할 수 있다.
- 토큰은 각 플랫폼마다 획득하는 방법이 조금씩 다르다.
- pudData
- 데이터를 설정한다.
- 고유한 키와 해당 키에 매핑할 데이터를 설정한다.
- 데이터는 여러 건 설정할 수 있다.
- 데이터는 문자열 타입만 설정할 수 있다.
메시지 전송하기
- 기존에는
sendAll
이라고 해서 최대 500개의 메시지를 HTTP 요청 딱 1번만에 보낼 수 있었다. - 그런데 2024년 여름에
sendAll
같은 배치(= 일괄전송) API들이 더 이상 사용될 수 없게 되었다. - 그래서 지금은
sendEach
같은 메소드를 통해서 메시지 1건당 요청 1번으로 보내야 한다.- 이것때문에 서버쪽에서 리소스 부담이 많아져서 커뮤니티에서 불만이 많았었고, 지금도 많다.
- 제목이랑 내용 등이 같으면 묶어서 토큰만 리스트로 붙여서 발송하는 방식이 있긴하다.
- 다만 모양만 일괄방송이고 내부 로직을 까보면 똑같이 반복 발송이다.
sendEach
도 기존과 동일하게 1번 실행할 때 최대 500개의 메시지를 인자로 전달할 수 있다.
- 전송 결과는 SendResponse라는 클래스에 담겨서 반환된다.
- SendResponse는 com.google.firebase.messaging 패키지에 포함되어 있다.
- 응답 결과를 얻는 과정은 다음과 같다.
- FirebaseMessaging.getInstance()를 통해 인스턴스를 획득한다.
- 메소드마다 반환 타입이 다르긴 하지만 메시지를 발송하면 BatchResponse로 반환하는 sendEach를 실행한다고 가정한다.
- 메시지를 발송 후 그 결과값인 BatchResponse에서
getResponses
를 실행해서 SendResponse 목록을 가져온다. - 결과에 따라 처리를 진행한다. (※ SendResponse를 res라는 이름의 변수로 선언했다고 가정)
- res.isSuccessful()
- 메시지 발송의 성공 여부를 반환한다. (boolean)
- res.getException().getMessage()
- 발송 실패 시 그 원인에 대한 메시지를 반환한다. (String)
- res.isSuccessful()