라벨이 FCM인 게시물 표시

Android FCM 토큰 관리 운영 가이드: 서버 동기화 및 만료 처리 방법

앱에 FCM 푸시 기능을 붙일 때, 처음에는 그냥 발급받은 토큰을 서버에 보내서 저장하면 끝나는 줄 알았습니다. 하지만 서비스를 이래저래 직접 운영하다 보니 이게 생각보다 손이 많이 가더군요. 사용자가 앱을 지웠다 다시 깔거나, 기기를 바꾸거나, 혹은 오랫동안 앱을 안 쓰면 토큰이 계속 바뀝니다. 이걸 제대로 관리 안 하면 유효하지 않은 토큰에 계속 푸시를 쏴서 서버 리소스만 낭비되고 발송 성공률 통계도 엉망이 됩니다. 자꾸 놓치는 부분이 생겨서, 실무 운영 중에 막히지 않도록 클라이언트와 서버 측의 FCM 토큰 관리 기준을 메모 형태로 정리해 둡니다. 1. 운영하다 보면 꼭 마주치는 토큰 문제들 처음 구현할 때 대충 넘어가면 나중에 운영계 데이터베이스를 보고 한숨을 쉬게 되는 상황들입니다. 한 번만 저장하고 방치: 최초 실행 때만 토큰을 서버에 보내고 이후 갱신을 안 함. 보안 불감증: 디버깅 편하게 하려고 onNewToken() 에서 받은 토큰을 무심코 로그에 그대로 출력함. 갱신 시각 누락: 서버 DB에 토큰만 딸랑 저장하고, 이 토큰이 언제 업데이트되었는지( updated_at 등) 기록하지 않음. 예외 상황 기준 없음: 로그아웃, 회원 탈퇴, 기기 변경 시 토큰을 어떻게 처리할지 정책이 없음. 실패 응답 방치: FCM 서버가 UNREGISTERED 같은 실패 응답을 주는데도 DB에서 안 지우고 계속 발송함. 재시도 로직 부재: 네트워크 불안정으로 서버 동기화가 실패했을 때, 재시도 없이 그냥 조용히 묻힘. 다기능 기기 미고려: 사용자 한 명이 폰과 태블릿을 동시에 쓸 수 있다는 점(1:N 관계)을 고려하지 않고 DB를 설계함. 운영 관점에서 FCM 토큰은 단순한 문자열이 아닙니다. 사용자, 기기, 앱 설치 인스턴스, 그리고 갱신 시각이 묶인 유기적인 데이터 로 접근해야 합니다. 2. 핵심 개념: FCM 토큰은 '앱 설치 인스턴스' 단위입니다 FCM 등록 토큰은 서버가 특정 사용자가 아니라 특정 기기에 설치된 앱 인스턴스 ...

[Android] FCM 수신 백그라운드 작업 WorkManager로 안전하게 분리하기 (실무 적용 코드)

앱을 개발하고 운영하다 보면 FCM(Firebase Cloud Messaging)을 연동할 일이 참 많습니다. 푸시 메시지가 올 때 단순히 알림만 띄우면 상관없는데, 메시지를 신호탄 삼아 서버에서 상세 데이터를 다시 긁어오거나 로컬 DB를 동기화해야 하는 경우가 꼭 생기더군요. 저의 경우도 처음에는 FirebaseMessagingService.onMessageReceived() 안에서 가볍게 네트워크 요청을 보냈다가, 앱이 백그라운드에 있을 때 작업이 툭 끊기거나 실패 시 재시도가 안 돼서 골치를 썩은 적이 있습니다. 자꾸 까먹기도 하고, 실무에서 실수하기 쉬운 부분이라 정돈해서 기록해 둡니다. 1. 운영하다 보면 자주 하는 실수 (내가 겪은 상황) FCM 수신 처리에서 문제가 생기는 코드는 보통 아래와 같은 상황을 간과할 때 발생합니다. onMessageReceived() 안에서 긴 네트워크 요청(API 호출)을 바로 실행함 실패하면 다시 시도해야 하는 작업을 일회성 처리로 대충 끝냄 앱이 백그라운드 상태일 때 OS 제약으로 작업이 중간에 강제 종료되는 상황을 고려 안 함 넘어온 data payload를 검증하지 않고 그대로 Worker 인풋으로 넘김 로그에 FCM 토큰, 서버 URL, 사용자 식별자(ID)를 그대로 남겨 보안 필터에 걸림 알림을 표시하는 UI 책임과 데이터 동기화 책임을 한 함수에서 모두 처리함 운영 관점에서는 FCM 수신 콜백을 "모든 작업을 수행하는 시작점"이 아니라, "작업을 분류하고 안전한 곳으로 위임하는 진입점"으로 보는 것이 좋습니다. 2. 해결 방법: 즉시 처리와 위임 처리 나누기 작업 성격에 따라 FCM 콜백에서 바로 끝낼지, WorkManager 로 넘길지 확실히 나눠야 유지보수가 편합니다. 제가 실무에서 잡은 기준은 이렇습니다. 작업 종류 처리 위치 이유 단순 알림 표시 onMessageReceived() 짧고 즉시 끝나는 작업입니다. payload 데이터 검증 onMessageRec...