FCM: 웹 푸시 알림 구현 시 발생한 오류 해결하기

김준기·2024년 10월 18일
0

Firebase Cloud Messaging(FCM)을 웹에서 구현하던 중 다음 오류가 발생했다:

firebase AbortError: Failed to execute 'subscribe' on 'PushManager': Subscription failed - no active Service

GitHub 이슈에서 해결책을 찾았다. 이유는 알 수 업지만, FCM 모듈에서 getToken 메소드 사용시 서비스 워커가 등록이 제대로 되지 않아 수동으로 활성화된 서비스 워커를 넣어주어야 하는 것이 핵심이다.

해결된 코드(Firebase JS SDK 버전 10.13.1):

import { initializeApp } from "https://www.gstatic.com/firebasejs/10.13.1/firebase-app.js";
import { getMessaging, getToken, onMessage, deleteToken } from "https://www.gstatic.com/firebasejs/10.13.1/firebase-messaging.js";

const vapidKey = ""; //웹 푸시 인증서 공개키
const firebaseConfig = { //  Firebase 구성 객체
  apiKey: "",
  authDomain: "",
  projectId: "",
  storageBucket: "",
  messagingSenderId: "",
  appId: "",
  measurementId: ""
};

initializeApp(firebaseConfig);
const messaging = getMessaging();

const init = () => {
  navigator.serviceWorker.getRegistration('/firebase-messaging-sw.js')
    .then((registration) => {
      if (registration) {
        console.log('서비서 워커 발견.');
        return registration;
      } else {
        console.log('서비스 워커 못찾음, 새로 등록함.');
        navigator.serviceWorker.register('/firebase-messaging-sw.js');
        return navigator.serviceWorker.ready; // 중요 서비서 워커가 활성화 될 때까지 기다리는 용도
      }
    })
    .then((serviceWorkerRegistration) => {
      return getToken(messaging, { vapidKey, serviceWorkerRegistration });
    })
    .then(currentToken => {
      if (currentToken) {
        // 여기에 대충 내 웹 서버로 토큰을 보내는 코드
        console.log('서버로 토큰 전송');
      } else {
        console.log('토큰 못찾음. ', currentToken);
      }
    })
    .catch(err => {
      console.error('에러 발생함: ', err);
    });
};

// 대충 사용자가 로그아웃 할 때 사용하면 될듯
const clearToken = () => {
  deleteToken(messaging)
    .then(() => {
      // 필요하다면 내 웹 앱 서버로 토큰 삭제 요청 보내기
      console.log('토큰 삭제 성공적');
    })
    .catch((err) => {
      console.error('토큰 삭제중 에러 발생. ', err);
    });
};

// 메시지 받기
onMessage(messaging, (payload) => {
  console.log('메시지 받음! ', payload);
});

// 알림 권한이 있으면 토큰 발급
// 함수로 감싸서 버튼 같은데 이벤트로 사용해도 좋을 듯
Notification.requestPermission().then((permission) => {
  if (permission === 'granted') {
    console.log('알림 권한이 허용됨.');
    init();
  } else {
    console.log('알림 권한이 없음');
  }
});
profile
코딩 잘하고 싶은 백엔드 개발자

0개의 댓글