//
Search

FCM 푸쉬 알림 구현

블로그로 정리해 올린 글입니다
작성자

알림 필요 시점

who
what
how
공모 참여 시
총대
공모 제목, 참여자 닉네임, 공모 id, 타입
token
공모 참여 취소 시
총대
공모 제목, 참여자 닉네임, 공모 id, 타입
token
거래 상태 변경 시
총대를 제외한 모든 참여자
공모 제목, 상태 설명, 공모 id, 타입
condition
댓글(채팅) 전송 시
전송자를 제외한 모든 참여자
공모 제목, 전송자, 댓글 내용
tokens
공모 작성 시
작성자를 제외한 모든 참여자
공모 제목, 공모 id, 타임
condition

사용 기술

FCM의 Firebase Admin SDK 방식

채택 이유

FCM

가장 러닝 커브가 낮고 익숙한 기술

Firebase Admin SDK

: Firebase가 제공하는, FCM 서버와 상호작용하여 작업할 수 있는 서버 라이브러리 집합
REST API를 활용하여 직접 fcm 서버에 요청을 보낼 수도 있으나, 더 편리한 방법을 채택함.
Firebase Admin SDK 방식 vs FCM 서버 프로토콜 방식

서버 개입의 필요성

(= 안드로이드 구현만으로 충분하지 않은 이유?)
데이터베이스 접근 필요

전송 방법

Token

Fcm이 발급한 Token에 직접적으로 알림 전송
Token은 사용자 기기 별 발급이 가능하다.
총대마켓의 경우, Member 당 하나의 fcm_token을 가진다.
public Message createMessage(FcmToken token, FcmData data) { return Message.builder() .setToken(token.getValue()) .putAllData(data.getData()) .build(); }
Java
복사

Tokens

Token 여러개에 직접적으로 알림 전송
최대 500개의 token까지 전송 가능
public MulticastMessage createMessages(FcmTokens tokens, FcmData data) { return MulticastMessage.builder() .addAllTokens(tokens.getTokenValues()) .putAllData(data.getData()) .build(); }
Java
복사

Topic

특정 주제를 구독한 token들에 알림 전송
public Message createMessage(FcmTopic topic, FcmData data) { return Message.builder() .setTopic(topic.getValue()) .putAllData(data.getData()) .build(); }
Java
복사

Condition

특정 조건을 만족하는 token들에 알림 전송
public Message createMessage(FcmCondition condition, FcmData data) { return Message.builder() .setCondition(condition.getValue()) .putAllData(data.getData()) .build(); }
Java
복사

전송 내용 방식

Notification

화면에 실제 표시될 알림을 전달하는 방식

Data

안드로이드에서 처리할 데이터를 전달하는 방식 // TODO

구현 과정

프로젝트 세팅

공식 문서 참고

테스트용 FCM Token [ 노출 금지 ] // TODO 우리건지 내건지 확인하기

고민포인트

1) 댓글방 상태 변경 시, condition vs tokens?

tokens
OfferingMember에서 참여자 목록 추출
장점: 구현 난이도 낮음, 전송 속도 빠름
단점: 최대 500개라는 한계 존재, 매번 데이터베이스 접근 필요
condition ⇒ topic으로 변경하기 TODO (참여자만)
장점: 데이터베이스 접근 필요 없음
단점: 전송 속도 느림 (하지만, 상태 변경의 경우 빠른 알림을 요구하지 않음)
참여자인가 [1] && 총대가 아닌가 [2]
[1] topic: member_of_offering_%d (총대 + 참여자) ⇒ (참여자)
[1] 구독: 공모 참여 시
[1] 취소: 공모 나가기 시
[2] topic: proposer_of_offering_%d (총대)
[2] 구독: 공모 개설 시
[2] 취소: 공모 삭제 시

2) 댓글 전송 시, condition vs tokens?

tokens
장점: 빠른 전송 속도
단점: 매번 데이터베이스 접근
OfferingMember 모두 뽑아서 본인만 제외
condition
참여자인가 [1] && 작성자가 아닌가 [2]
[1] topic: member_of_offering_%d
[2] topic: writer_of_comment_%d
[1] 구독: 공모 참여 시
[1] 취소: 공모 나가기 시
[2] 구독: 댓글 작성 시
[2] 취소: 댓글 작성 완료 시
⇒ 위 방식은 작성자가 아닌 토픽 구독이 어렵다.

3) Tokens vs Topic(Condition)

토픽 선정 이유: 토큰들을 가져오려면 매번 DB에 접근해야 한다. 특히 broadcast 방식일 경우 member 테이블을 풀스캔해야하는 상황 발생 → 따라서 토픽을 통해 전달하도록 한다.
알게된 점: topic은 느리고 tokens는 빠르다. ⇒ 그래서 채팅 전송 로직에는 tokens 사용하도록 했다 (빠른 알림을 요구하므로)

최종 결정 topic

1. 사용자인가: member 2. 특정 공모의 총대 혹은 참여자인가: member_of_offering_%d 3. 특정 공모의 총대인가: proposer_of_offering_%d
Java
복사

개발 환경 분리

로컬
dev
prod

추후 구현할 사항

1) 비동기 처리

상황: 앱 테스트를 통해, 알림 로직이 포함된 API의 경우 속도가 저하됨을 확인함
해결: 비동기 처리

TODO

데이터 전송 방식 (noti vs data 정리)
댓글방 상태 변경: condition 대신 참여 topic 사용하는 방식으로 변경
로깅 확인