본문 바로가기

[PWA] FCM으로 알림 기능 구현하기 (1) : Notification API

[PWA] FCM으로 알림 기능 구현하기 (1) : Notification API

 

FCM(Firebase Cloud Message) 기반으로 PWA 알림 기능을 구현해보았다. 정석이랄 게 없어서 이것저것 정말 많은 레퍼런스를 찾아보고 시도해보면서 나름대로 의도한 기능을 구현할 수 있었다.

 

우선 구현한 기능은 아래와 같다. 크게 백그라운드와 포그라운드, 웹 브라우저와 모바일 브라우저(PWA 앱 포함)로 나뉜다.

 

[단어 정의]
- 포그라운드(foreground) : 사용자가 해당 앱을 사용하고 있는 상태
- 백그라운드(background) : 앱이 사용자와의 상호 작용이 없는 상태로 홈 버튼을 누르거나 다른 앱으로 전환한 상태

 

 

구현한 기능 

 

포그라운드 

  • 사용자가 앱을 사용하고 있을 때, 푸쉬 알림이 뜸
  • 알림 메시지에는 제목, 내용, 앱 아이콘, 필요한 경우 이미지까지 포함
  • 앱을 클릭할 시, 관련 링크로 이동 
  • 구현 방식 요약 
    1. FCM의 onMessage 메서드로 new Notification으로 브라우저에서 기본적인 알림 객체를 생성하여 필요한 데이터 넘겨줌  
      + onclick 이벤트 핸들러로 클릭 메서드 구현
    2. 안드로이드인 경우, new Notification 적용이 안 되기 때문에 serviceWorker로 구현
      + 클릭 이벤트는 serviceWorker의 message 이벤트를 이용하여 구현

 

백그라운드 

  • 사용자가 앱을 사용하고 있지 않을 때, 푸쉬 알람이 뜸 
  • 이 때 웹 브라우저와 모바일(PWA 앱 포함) 작동 방식이 
  • 구현 방식 요약
    1. FCM의 onBackgroundMessage 메서드로 service worker의 showNotification 메서드를 사용하여 알림 객체 생성하여 필요한 데이터 넘겨줌
      + service worker 내 notificationclick 이벤트를 등록하여 클릭 이벤트 구현

 

 

구현 모습 및 배경 지식

 

알림 권한 요청

  • 알림을 표시하기 위해서는 우선 각 사용자의 브라우저에 '알림 권한'을 요청하고 수락을 받아야 한다.
  • 사용자에게 알림 권한을 받으면 특정 디바이스를 고유하게 식별해주는 토큰을 해당 브라우저에서 발급받아 서버에 넘겨줄 수 있다.
  • 토큰을 발급해서 서버에 넘겨줘야 하는 상황은 아래와 같다.
    1. 최초 로그인 후
    2. 다른 기기로 전환했을 때 + 자동 로그인 
      (웹 -> 모바일로 앱을 이어서 사용할 시 토큰을 다시 발급받아서 알림 받는 매개체를 변경)
  • 특히 우리 서비스는 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/

 

Notification Examples - Base Site

This is a set of example notifications that are referenced throughout the web push book content.

web-push-book.gauntface.com

 

  • 공식 레퍼런스로 기본적인 알림 구현 세팅에 참고했다

https://firebase.google.com/docs/cloud-messaging/js/receive?hl=ko 

 

자바스크립트 클라이언트에서 메시지 수신  |  Firebase 클라우드 메시징

Google I/O 2023에서 Firebase의 주요 소식을 확인하세요. 자세히 알아보기 의견 보내기 자바스크립트 클라이언트에서 메시지 수신 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장

firebase.google.com

 

  • 웹 푸시 기능에 대한 원리

https://web.dev/explore/notifications?hl=ko

 

알림  |  web.dev

이 페이지는 Cloud Translation API를 통해 번역되었습니다. Switch to English 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 알림 웹 푸시 및 알림 개요 푸시 메시지

web.dev

 

728x90
⬆︎