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('알림 권한이 없음');
}
});