VITE + React + PWA 환경 FCM 사용기 (푸시알림)

모아나·2025년 2월 18일
0

근태관리 서비스 프로젝트에서 알바생(user)가 출/퇴근 버튼을 눌렀을 때, 사장님(admin)에게 푸시알람을 보내는 구현을 맡게됐다.

FCM(Firebase Cloud Messaging)은 푸시알림을 쉽게 구현할 수 있게 해주고, 멀티플랫폼 지원과 일정 사용량 무료 등 장점이 많다. 우선 FCM을 사용해 어떻게 구현해야할 지 대략적인 그림을 다이어그램으로 그려보았다.

테스트 코드 (우선 해보기)

기능을 서비스에 넣기 전에 알람을 받고 콘솔에 띄워보는 코드를 블로그와 공식문서를 참고해 테스트해보았다.

  1. Firebase 콘솔에 들어가 프로젝트를 생성한다.
  2. 앱추가 -> 웹 -> 앱등록 -> Firebase SDK 추가에 있는 내용 따라하기
  3. 웹 사용자 인증 정보
    • 프로젝트 설정 창 -> 클라우드 메시징 탭 -> 웹 푸시 인증서 -> 키 쌍 가져오기 또는 생성하기
    • 여기서 키 쌍은 나중에 VAPID 에 적어줄 거라 복사해놓습니다.

백그라운드, 포그라운드 알람

둘 다 firebase 초기화가 필요한데, 서비스워커와 클라이언트가 실행 환경이 다르기 때문에 초기화가 각각 별도로 이뤄져야 한다. 클라이언트 초기화는 알림 구독, 토큰 요청, 포그라운드 알림처리를 위해 필요하고, 서비스 워커 초기화는 백그라운드 알림 처리를 위해 필요하다.

토큰 관리에 대한 고민

브라우저에서 알람허용이 되어 있지 않고 토큰을 요청하면 blocked 됐다는 에러가 뜬다. 따라서 토큰을 발급 받으려면 반드시! 유저의 알람 허용이 필요하다.

이는 사용자에게 알람 허용을 받아야만 하는데,
Notification.requestPermission()을 통해 알람 팝업을 띄워 사용자의 입력을 받을 수 있다.
사용자에게 알람 권한을 받으면 이 디바이스를 식별해주는 토큰을 발급받아 서버에게 전송해줄 수 있다.

이 메서드의 반환값으로는 권한 상태에 대한 string을 Promise로 담아 보낸다.

  • granted : 유저가 알람 허용을 했을 때
  • denied : 유저가 알람을 차단함
  • default : 유저의 결정사항은 모르지만 앱이 denied 처럼 동작함



근데 매번 앱을 실행할 때마다 이 팝업을 띄워줄 수는 없다..! 현재 권한이 무엇인지 Notification.permission 으로 확인이 가능한데 이는 접속한 브라우저에 따라 다르다.

처음에는 회원가입 시 최초로 한 번 팝업을 띄워주고 허용을 받으면 토큰을 발급받아 서버로 전송해주는 식으로 생각했다. 그렇게 되면 로그인 했을 때, Notification.permission 이 grant이면 토큰을 발급받아 갱신해주고 별도로 팝업을 띄워줄 필요도 없이 알람을 받아볼 수 있기 때문이다.

하지만 다른 디바이스로 접속했을 때 문제가 생긴다.
예를 들어, 회원가입을 해서 권한을 허용한 후 다른 디바이스에서 로그인한다면?
로그인화면에서 Notification.requestPermission()을 띄우지 않기 때문에 알람 허용을 받을 수가 없고, Notification.permissiondefault만 나올 것이다.

이러한 문제로 로컬스토리지로 알람 권한 요청을 한 적이 있는지 저장하기로 했다.
1. 로컬스토리지 isPermissionChecked를 false를 기본으로 한다.
2. 로그인 또는 회원가입 후, 메인페이지 이동
3.isPermissionCheckedfalse이면 Notification.requestPermission()으로 알람 권한 허용여부를 사용자에게 받는다. 그 후 true로 바꾼다.
4. 로그아웃 시 서버에 유저 관련 FCM 토큰 삭제 요청을 한다.
5. 다음 로그인 또는 회원가입 시 isPermissionChecked가 true이면 Notification.permission을 확인한다.
6. Notification.permission 이 granted이면 토큰을 발급한 후 서버에 전송하고 denied면 토큰을 발급받지 않는다.
7. 추가로, 앱 내 알람 토글은 Notification.permission을 따르고, 알람을 다시 켤 경우, Notification.requestPermission()으로 인터페이스를 띄워 사용자의 알림권한 허용을 받는다.

Tip. 테스트 시에 크롬에서 알람허용을 끄려면 크롬 설정>개인정보 보호 및 보안> 사이트 설정> 알림> 알림 전송이 허용됨에 해당 사이트 삭제

트러블 슈팅

알람 두 번 가는 현상

알람 두 번 감: https://doyu-l.tistory.com/687

notification객체로 담아보내주면

따라서 data받은걸 직접 notificationOption에 담아 보내줘야 한다.
이를 위해 notifications API를 참고하여 알람 객체를 만들어주었다. https://developer.mozilla.org/en-US/docs/Web/API/Notifications_API

알람옵션 예제사이트

profile
Make things

0개의 댓글