프론트/Vue

[Nuxt] PWA + firebase Push 알림 기능 추가 및 확인

ZestLee 2022. 2. 6. 20:40

2019-11 에 작성한 글입니다.

지난 포스트에서 SSR 확인까지 다뤄 보았고, 이제 지금까지 만들어 온 프로젝트에 PWA를 적용시킬 것입니다.

적용시키기 전에, 먼저 PWA에 대해 알아보고 들어갈까요?

위 페이지에서 관련 내용을 확인할 수 있습니다.

간단하게 말하자면 PWA는, 설치 없이 앱처럼 동작하고, 바탕화면에 앱 아이콘을 저장할 수 있고, 푸시알림을 줄 수가 있고, 오프라인에서도 접근이 가능합니다.

저는 그 중, 푸시알림 기능에 관련하여 포스팅을 하겠습니다.

 

Firebase 클라우드 메시징(FCM)은 무료로 메시지를 안정적으로 전송할 수 있는 교차 플랫폼 메시징 솔루션입니다. 저는 구글에서 제공하는 firebase를 이용하여 푸시 알림 기능을 추가하겠습니다.

 

Push 알림으로 들어가기 이전에, firebase 가입부터 해 주세요.

가입을 완료한 후에, 메인에 있는 시작하기를 누른 후 ‘프로젝트를 추가’ 를 눌러 줍니다. 다음을 눌러 프로젝트를 만들어 준 후, ‘계속’을 눌러 프로젝트에 들어가면 현재 만들어진 프로젝트를 확인할 수 있습니다.

그 후, 웹앱을 추가해 주기 위하여 밑의 빨간 박스를 클릭해 주세요.

앱 이름을 임의로 작성하여 웹앱을 생성하고, 콘솔로 이동한 다음, 좌측 메뉴에서 설정 버튼을 클릭합니다.

하단으로 내리면, Firebase SDK snippet 부분이 보입니다. 이는 firebase 서비스를 위한 정보들이므로 따로 메모해 두는 것을 추천합니다.

탭에서 클라우드 메시징을 선택하면, 클라우드 메시징을 위한 여러 정보들이 나옵니다. 이 정보들 역시 기억해 주세요.

자, 이제 Push 알림 기능을 추가해 보겠습니다.

1. Push 알림 기능 추가

a. pwa 모듈 추가

저는 프로젝트를 만들 때 pwa 모듈을 추가해 줬습니다. 물론, 이 pwa 모듈은 프로젝트를 만든 후에 추가도 가능합니다. 프로젝트를 만들 때 추가해 주지 않은 분들은 터미널에 아래를 입력하여 pwa 모듈을 설치해 주세요.

npm i --save @nuxtjs/pwa

이제 nuxt.config.js 파일에 가서 방금 설치해 준 pwa 모듈을 추가해 줍니다.

modules: [
  ...
  '@nuxtjs/pwa'
]

b. manifest 추가

모듈을 추가해 주셨다면, 이제 manifest를 추가해 주세요. 매니페스트는 앱의 아이콘, 이름 등을 설정해 줄 수 있는데, 저는 현재 구글의 클라우드 메시징을 이용할 것이기 때문에, 매니페스트에 gcm_sender_id를 추가해 주겠습니다.

gcm_sender_id는 Firebase messaging서비스를 수신하기 위한 고정값입니다. 103953800507를 입력해 주세요. (이는 프로젝트에 따라 다른 것이 아닌, 모든 웹앱에 대해 동일합니다.)

manifest: {
  gcm_sender_id: '103953800507'
},

c. sw.js 추가 및 작성

권한을 받고, 디바이스의 토큰을 받기 위하여 sw.js 를 plugins 폴더에 생성 후 아래 내용을 작성하겠습니다.

import firebase from 'firebase'

if (process.client) {
    if (!firebase.apps.length) {
        firebase.initializeApp({
            apiKey: '',
            authDomain: '',
            databaseURL: '',
            projectId: '',
            storageBucket: '',
            messagingSenderId: '',
            appId: ''
        })
        const messaging = firebase.messaging();

        messaging.requestPermission()
        .then(function() {
          console.log('Notification permission granted.');
          return messaging.getToken()
        })
        .then(function(result) {
            console.log("The token is: ", result);
        })
        .catch(function(err) {
          console.log('Unable to get permission to notify.', err);
        });

        messaging.onMessage(function(payload) {
        console.log("Message received. ", payload);
        });
    }

}

export default firebase

Firebase SDK snippet 정보를 참고하여 공백을 채워 주세요.

이는 SSR에서는 적용이 되지 않기 때문에, 클라이언트에서만 작동시키겠다는 process.client 조건을 추가해 줬습니다. 권한 요청을 하고, 권한을 받을 경우, getToken을 실행 후, 토큰을 받으면, 그 토큰을 콘솔에 보여 주는 형태입니다. onMessage는 잠시 후에 설명해 드리겠습니다.

작성했으니, 이 플러그인을 프로젝트에 적용시켜야 하겠죠? nuxt.config.js에 해당 플러그인을 추가해 주세요.

plugins: [
  '~/plugins/sw.js'
]

이제 실행해 보겠습니다. npm run dev 후, 해당 페이지로 들어가 주세요. (https:// 혹은 localhost에서만 pwa가 적용되기 때문에, 로컬에서 진행하였습니다.)

페이지 접속하니, 아래처럼 권한 요청 메시지가 뜹니다.

허용 후 브라우저 콘솔에서 내용을 확인해 주세요.

이는 firebase-messaging-sw.js 파일이 없어서 생긴 에러입니다. firebase 이벤트를 수신하기 위해서는 최상위에 firebase-messaging-sw.js를 생성하고, 여기에 서비스 워커를 정의해야 합니다. 그럼 Nuxt.js 프로젝트에서는 static 폴더에 생성해야 되겠죠? static 폴더에 firebase-messaging-sw.js 파일을 생성해 주고, 아래 내용을 입력해 주세요.

importScripts('https://www.gstatic.com/firebasejs/4.8.1/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/4.8.1/firebase-messaging.js');

firebase.initializeApp({
    apiKey: '',
    authDomain: '',
    databaseURL: '',
    projectId: '',
    storageBucket: '',
    messagingSenderId: '',
    appId: ''
});

const messaging = firebase.messaging();
messaging.setBackgroundMessageHandler(function(payload){
    const title = "All Find";
    const options = {
            body: payload.data.status
    };

    return self.registration.showNotification(title,options);
});

firebase-messaging-sw.js

코드 설명은 잠시 후 해 드리겠습니다.

페이지를 새로고침 하고, 콘솔창을 확인해 주세요.

디바이스의 토큰이 보입니다.

2. Push 알림 확인

Push 알림을 확인하기 위해서 postman 앱을 사용했습니다. 없으신 분은.. 아래에서 다운받아 주세요.

현재 켜 놓은 로컬 페이지를 끄고, https://fcm.googleapis.com/fcm/send에 POST로 아래 내용을 담아 요청을 날리겠습니다.

{
	"to": "[디바이스 토큰]",
	"notification" : {
		"title": "알림테스트 타이틀",
		"body": "알림테스트 내용",
		"sound": "default"
	}
}

body의 raw를 클릭하여 JSON으로 담아 주세요.

Conten-Type은 apllication/json, Authorization은 key=[클라우드 메시징의 서버 키]

Send를 눌러 요청을 날리면,

서버를 껐다 켜서 포트가 다른 점 이해 부탁드립니다 ^^;;

알림이 도착합니다.

이제 다시 페이지로 접속해 주시고, 페이지를 보고 있는 동시에 요청을 날려 주세요.

뭔가 이상하죠? 아까와는 다르게, 알림이 도착하지 않습니다. 브라우저의 콘솔을 확인해 주세요.

아까 sw.js에 작성한 onMessage가 작동했네요! 이를 이용하여 현재 페이지를 보고 있을 경우에는, 페이지 자체에 실시간 알림이 뜨도록 만들면 되겠네요. 😍

firebase 공식 홈페이지를 확인하시면, 포어그라운드와 백그라운드일 때 알림 설정해 주는 법을 확인할 수 있습니다. 제가 sw.js에서 설정해 준 onMessage는 포어그라운드일 때의 알림 설정이고, firebase-messagins-sw.js에서 설정해 준 setBackgroundMessageHandler는 백그라운드일 때의 알림 설정입니다. 이때문에 방금과 같은 현상이 있었던 것입니다.

이렇게 하여, 페이지를 종료했을 때와, 페이지를 보고 있을 때의 알림을 확인해 보았습니다.