잉크링크
프로젝트 진행 중 일정 시간마다 사용자에게 푸시 알림을 보내기 위한 기능이 필요했습니다.
flutter
개발자분들이Firebase
를 사용하고 계셨고App Test
와다양한 플랫폼 지원
및무료 사용
의 장점으로 푸시 알림을FCM
으로 선정하였습니다.해당 포스팅은
FCM
에 대한 개념을 정리한 포스팅입니다.
Firebase
에는 2개의 token
이 존재합니다.
FCM Token
: 앱이 사용자 디바이스에서 처음 실행
될 때 또는 FCM Token이 갱신
될 때, FCK SDK
는 해당 디바이스에 대한 고유 토큰(FCM Token)을 생성
합니다. Access Token
: Firebase
서버에 엑세스하거나 Firebase
서비스에 인증하기 위해 사용되는 토큰입니다.Firebase
서비스를 이용하여 FCM Message
를 전송할 때 사용됩니다.FCM Token
은 아래와 같이 변경될 수 있습니다.
App 재설치
: 사용자가 앱을 삭제했다가 다시 설치하는 경우App 데이터 삭제
: 사용자가 앱 데이터를 삭제하는 경우새 기기 또는 기기 초기화
: 사용자가 앱을 새 기기에 설치하거나 기기를 초기화하는 경우Token 갱신
: FCM
에서 시스템 정책에 따라 주기적으로 토큰을 갱신
Token
의 개념을 정리하기 전에는 하나의 계정에 2개의 기종을 생각하지 못하고 단순히
- 회원 테이블에
FCM Token
을 저장하는 속성을 추가하면 되겠구나?라고 생각했습니다.
그런데
FCM Token
은 사용자의 특정 기기를 식별하기 위한 토큰이라면 만약 A 사용자가 1번의 핸드폰과 2번의 핸드폰으로App
을 사용하면 하나의 핸드폰에만 푸시 알림이 가지 않을까? 라는 의문점이 생겼습니다.
이렇게 하자!
즉, 2개의 FCM 토큰을 저장하기 위해 회원 Table
이 아닌 FCM Table
을 만들고, 사용자 계정과 기기의 FCM 토큰 간에 1:N
관계를 구성하면 서버는 특정 사용자의 모든 기기에 알림을 전송
할 수 있게 됩니다.
FCM Token Table | |
---|---|
토큰 ID | 고유 식별자, PK, AI |
사용자 ID | 회원 테이블의 사용자 ID와 연결, FK |
FCM 토큰 | FCM Token, UK |
FCM Token
은 고유한 값이니까PK
로 해도 되지 않을까?라고 생각할 수 있습니다. 이러한 경우 스키마 자체는 별도의 토큰 ID를 관리할 필요 없이, FCM 토큰 자체를 식별자로 사용함으로써 데이터베이스 스키마가 단순해지게 됩니다.
하지만 아래의 문제가 발생할 수 있습니다.
갱신의 복잡성
: FCM 토큰은 변경될 수 있습니다. 즉, 기본 키가 변경되는 경우 단순한 값의 업데이트가 아닌 연관된 모든 외래 키 관계를 업데이트해야 하는 복잡성이 생길 수 있습니다.
인덱스 성능 저하
: FCM 토큰은 상대적으로 긴 문자열입니다. FCM 토큰을 기본 키로 사용하게 되면 정수형의 키보다 인덱스의 크기가 커지며 데이터 조회 시간에 영향을 줄 수 있습니다.
보안
: FCM 토큰을 직접적으로 외부에 노출하는 API 설계는 잠재적인 위험이 존재합니다.
정수형 키가 외부에 노출
되더라도, 이 키만으로는 사용자의 기기에 접근하거나 메시지를 보낼 수 있는 권한이 없지만,
FCM 토큰을 API를 통해 직접 반환
하게 되면, 이 토큰을 탈취한 악의적인 사용자가 해당 사용자의 기기로 원하지 않는 메시지를 보낼 수 있는 권한을 얻을 수 있습니다.
- 서버는
FCM
과의 안전한 통신을 위해Access Token
을 요청합니다. 서버는 이 토큰을 이용해FCM
접근할 수 있는 권한을 획득합니다.보통 서버는
Firebase Admin SDK
를 사용해 이러한 인증을 자동화하고,Access Token
을 안전하게 관리하게 됩니다.
- 아래 과정을 통해 서버는 푸시 알림을 보낼 때 사용할 수 있는 각 클라이언트의 식별자, 즉
FCM Token
을 갖게 되고, 서버는 이 토큰을 사용해 특정 클라이언트 기기에 메시지를 보낼 수 있습니다.
사용자가 App
을 처음 실행하는 경우 (또는 앱 데이터 삭제 후 재실행, 앱 업데이트 후 등), FCM
은 고유한 FCM Token
을 생성하고 이를 Client(Android)
에 전달합니다.
Client(Android)
는 받은 FCM Token
을 서버에 전송합니다.
- 아래 과정을 통해 서버는 일정 시간에 모든 사용자의 기기에 알림을 보내게 됩니다.
만약 10개의 푸시 알림 중 1개의 토큰이 유효하지 않다면, FCM
은 유효한 9개의 토큰에 대한 알림을 전송하고, 유효하지 않은 1개의 토큰에 대해서는 오류 메시지를 반환합니다.
일반적으로 오류 메시지는 아래와 같은 형태로 구성됩니다.
NotRegistered
: 앱이 사용자의 디바이스에서 삭제되었거나 토큰이 더 이상 유효하지 않은 경우InvalidRegistration
: 토큰의 형식이 잘못된 경우서버는 이러한 오류 메시지를 응답받게 된다면 유효하지 않은 토큰을 데이터베이스에서 삭제하거나 비활성화
하거나 클라이언트에게 토큰을 재요청
또는 사용자에게 앱을 업데이트
요청 등 다양한 방법을 시도할 수 있습니다 : >