FCM(Firebase Cloud Message) 기반으로 PWA 알림 기능을 구현해보았다. 정석이랄 게 없어서 이것저것 정말 많은 레퍼런스를 찾아보고 시도해보면서 나름대로 의도한 기능을 구현할 수 있었다.
우선 구현한 기능은 아래와 같다. 크게 백그라운드와 포그라운드, 웹 브라우저와 모바일 브라우저(PWA 앱 포함)로 나뉜다.
[단어 정의]
- 포그라운드(foreground) : 사용자가 해당 앱을 사용하고 있는 상태
- 백그라운드(background) : 앱이 사용자와의 상호 작용이 없는 상태로 홈 버튼을 누르거나 다른 앱으로 전환한 상태
구현한 기능
포그라운드
- 사용자가 앱을 사용하고 있을 때, 푸쉬 알림이 뜸
- 알림 메시지에는 제목, 내용, 앱 아이콘, 필요한 경우 이미지까지 포함
- 앱을 클릭할 시, 관련 링크로 이동
- 구현 방식 요약
- FCM의 onMessage 메서드로 new Notification으로 브라우저에서 기본적인 알림 객체를 생성하여 필요한 데이터 넘겨줌
+ onclick 이벤트 핸들러로 클릭 메서드 구현 - 안드로이드인 경우, new Notification 적용이 안 되기 때문에 serviceWorker로 구현
+ 클릭 이벤트는 serviceWorker의 message 이벤트를 이용하여 구현
- FCM의 onMessage 메서드로 new Notification으로 브라우저에서 기본적인 알림 객체를 생성하여 필요한 데이터 넘겨줌
백그라운드
- 사용자가 앱을 사용하고 있지 않을 때, 푸쉬 알람이 뜸
- 이 때 웹 브라우저와 모바일(PWA 앱 포함) 작동 방식이
- 구현 방식 요약
- FCM의 onBackgroundMessage 메서드로 service worker의 showNotification 메서드를 사용하여 알림 객체 생성하여 필요한 데이터 넘겨줌
+ service worker 내 notificationclick 이벤트를 등록하여 클릭 이벤트 구현
- FCM의 onBackgroundMessage 메서드로 service worker의 showNotification 메서드를 사용하여 알림 객체 생성하여 필요한 데이터 넘겨줌
구현 모습 및 배경 지식
알림 권한 요청
- 알림을 표시하기 위해서는 우선 각 사용자의 브라우저에 '알림 권한'을 요청하고 수락을 받아야 한다.
- 사용자에게 알림 권한을 받으면 특정 디바이스를 고유하게 식별해주는 토큰을 해당 브라우저에서 발급받아 서버에 넘겨줄 수 있다.
- 토큰을 발급해서 서버에 넘겨줘야 하는 상황은 아래와 같다.
- 최초 로그인 후
- 다른 기기로 전환했을 때 + 자동 로그인
(웹 -> 모바일로 앱을 이어서 사용할 시 토큰을 다시 발급받아서 알림 받는 매개체를 변경)
- 특히 우리 서비스는 ios(모바일)인 경우 네이티브로, 웹과 안드로이드(모바일)인 경우에는 PWA로 구현했기 때문에 토큰 발급 후, 기기 정보(ios인지 aos인지)까지 넘겨주었다.
let currentDevice;
// ios 판별 함수
if (isIOSApp()) {
currentDevice = "iOS";
} else {
currentDevice = "AOS";
}
// 서버로 토큰 정보와 디바이스 정보 넘김
const res = await useAuthService().signup({
push_token: token,
device: currentDevice,
});
- 아래와 같은 함수를 firebase.js 파일 안에 생성하여 루트 경로에서 호출해주었다.
import { initializeApp } from "firebase/app";
import { getMessaging, getToken, onMessage } from "firebase/messaging";
.
.
// 루트 경로에서 호출하여 알림 권한 로직을 구현했다.
export async function getFCMToken() {
// firebase는 csr에서만 동작하는 모듈, client 모드인지 확인하는 조건문 추가 (Nuxt3)
if (process.client) {
const app = initializeApp(firebaseConfig);
const messaging = getMessaging(app);
const currentToken = await getToken(messaging, {
vapidKey:
// 키값 입력
});
// 토큰이 없는 경우, 권한 요청 후 빈 스트링 '' 리턴
if (!currentToken) {
console.error(
"No registration token available. Request permission to generate one.",
);
Notification.requestPermission();
return "";
}
return currentToken;
}
}
Notification API
- Notification API는 주요 브라우저에서 지원하는 API로 웹 애플리케이션에서 알림을 표시할 수 있게 해준다.
- 아래 이미지와 같이 구현하기 위한 코드는 다음와 같다. (포그라운드 일부 코드 인용)
// FCM 포그라운드 onMessage 메서드 일부 인용
onMessage(messaging, (payload) => {
// 알림 타이틀
const notificationTitle = payload.data.title;
// 알림 옵션 (내용, 이미지, 로고 이미지 등)
// 알림 옵션 (내용, 이미지, 로고 이미지 등)
const notificationOptions = {
body: payload.data.body,
image: payload.data.image_url,
icon: // 이미지 내 아이콘 정적 에셋 첨부했음
};
// 알림 객체 생성 시 제목, 옵션 전달
const notif = new Notification(
notificationTitle,
notificationOptions,
);
......
payload 예시
테스트
- 추천 : 서버에서 테스트 커스텀 API 만들어서 실행 (postman이나 swagger)
- 다른 방법 : FCM 서비스 내에서 아래와 같이 기본적인 알림 테스트까지는 구현 가능 (랜딩 URL과 같은 추가 데이터는 보낼 수 없음)
맥 OS 관련 유의사항
- 데스크톱 브라우저(크롬)의 경우, 아래와 같이 브라우저에서의 알림 허용과 더불어 맥OS 설정에서도 알림 설정을 따로 허용해줘야 함.
참고하면 좋을 레퍼런스
- Notification 항목에 대해 자세하게 설명 및 실습해볼 수 있는 레퍼런스
https://web-push-book.gauntface.com/demos/notification-examples/
- 공식 레퍼런스로 기본적인 알림 구현 세팅에 참고했다
https://firebase.google.com/docs/cloud-messaging/js/receive?hl=ko
- 웹 푸시 기능에 대한 원리
https://web.dev/explore/notifications?hl=ko
728x90
'📌 대외 활동 > 2311~ Look : AI 기록 서비스' 카테고리의 다른 글
[PWA] FCM으로 알림 기능 구현하기 (3) : 포그라운드 (0) | 2024.01.18 |
---|---|
[PWA] FCM으로 알람 기능 구현하기 (2) : 백그라운드 (0) | 2024.01.15 |
[Nuxt3 / PWA] service worker로 앱 오프라인 캐싱하기 (0) | 2023.12.04 |
PWA(Progressive Web Application)란? (0) | 2023.11.24 |
react와 vue 비교 (0) | 2023.11.24 |