Nuxt + PWA + Firebase Cloud messaging 이젠 눈감고도 설치하죠?

2020. 3. 28. 00:30Web

목차

  • 서론
  • Firebase Project 생성하기
  • Firebase 설정 값 획득하기
  • PWA 라이브러리 설치/설정 하기
  • Service Worker 작성하기
  • Token으로 알림 발송해보기
  • 다중 Token으로 다수에게 알림 발송해보기

 

 

서론

Nuxt.js 를 사용하여 Firebase에서 제공하는 Cloud messaging 이하 FCM 푸시 알림을 설정하는것은 정말이지 

Amazing 하도록 간단합니다. Firebase 프로젝트 추가하고 설정하는게 더 귀찮은듯 합니다.

 

 

PWA는 Progressive Web App 이라고 뭐 대충 그냥 

출처: https://developer.mozilla.org/ko/docs/Web/Progressive_web_apps/%EC%86%8C%EA%B0%9C

역시 MDN 설명을 잘 해주는군요.

 

 

 

 

Nuxt에는 PWA가 라이브러리로 존재하므로 이걸 이용해서 푸시알림을 구현해보도록 하겠습니다.

가장 많은 참고를 한 블로그는 Lee Youngwoo님의 All Find 개발기 게시글

 

All Find 개발기 (5) — NUXT.js + PWA + firebase Push 알림 기능 추가 및 확인

바이트(BYIT)의 All Find는 Nuxt.js+PWA+Vuetify로 작성되었습니다. 작성 중 특이사항 및 삽질 경험을 글로 남기려 합니다.

medium.com

사실 주의사항이 눈에 띄지 않아 생각보다 헤맸습니다.

저는 nuxt로 붙여보는것은 처음이었는데, 그것만 아니면 정말 쉽네요

 

 

 

 

Nuxt Project를 새로 만드는 것이 아닌, 현재 진행중이라는 것에 가정하에 진행됩니다.

 

 

 

Firebase 프로젝트 생성하기

Firebase 프로젝트 생성하기

 

Google Firebase Project 생성

다른 게시글을 작성하기 앞서 항상 겹칠 거 같아 Firebase를 생성하는 방법을 따로 기술해보고자 합니다. 여타 사이트나, 블로그, 책, 동영상에도 많이 기술되고 있겠지만 항상 자료는 새로 변하기 마련이죠... 작..

gmyankee.tistory.com

 

 

 

Firebase 설정 값 획득하기

Firebase 콘솔로 이동하신 뒤 프로젝트 개요 옆에 있는 톱니바퀴를 클릭하여 프로젝트 설정으로 이동합니다.

Firebase Console

Firebase Console -> 프로젝트 개요 -> 톱니바퀴 -> 프로젝트 설정

 

 

 

이동하셨다면 스크롤 을 살짝 내려보면

Firebase console 프로젝트 설정

위 와 같은 화면이 보이는데, firebaseConfig 변수에 있는 정보들이 필요로 하니 창을 띄워두거나 어디다가 적어두시죠

그 다음  클라우드 메시징 탭 메뉴로 이동하셔야 합니다.

 

 

Firebase Console - 프로젝트 설정 - 클라우드 메시징

여기서 이전 서버 키 를 마찬가지로 띄워두거나 어디다가 적어두시기 바랍니다.

강조를 위해 CC2019를 켰습니다..

 

 

 

 

 

 

PWA 라이브러리 설치/설정 하기

PWA 공식 홈페이지

 

 

package.json

// package.json
{
  "name": "z__z",
  "version": "1.0.0",
  "description": "Yankee Tutorial",
  "author": "yankee",
  "private": true,
  "config": {
    "nuxt": {
      "host": "0.0.0.0",
      "port": "3000"
    }
  },
  "scripts": {
    "dev": "nuxt",
    "build": "nuxt build",
    "start": "nuxt start",
    "generate": "nuxt generate",
  },
  "dependencies": {
    "@nuxtjs/pwa": "^3.0.0-beta.20",
  },
  "devDependencies": {
    "@nuxtjs/vuetify": "^1.0.0"
  }
}

예시니깐 대충 dependecies만 봐주시면 될 것 같습니다.

@nuxtjs/pwa 저는 귀찮아서 대충 베타 로 설치했습니다. 갓갓갓 vscode에서는 ctrl + space로 자동완성 때리면

알아서 서버에서 버전 띄워주거든요 정말 개 꿀 기능입니다.

 

저처럼 package.json으로 설치하는 분들은 npm install 해주시면 됩니다.

 

 

 

nuxt.config.js

// nuxt.config.js
export default{
    // ... 생략
    modules: [
        '@nuxtjs/pwa',
    ],
    plugins: [
    	{ src: "@/plugins/sw.js", ssr: false },
    ],
    manifest: {
      gcm_sender_id: '103953800507',
    },
    // ... 생략
}

1. nuxt.config.js에서 modules에 @nuxtjs/pwa 를 추가해줍니다.

2. plugins에 { src: "@/plugins/sw.js", ssr: false } 를 추가합니다.

3. manifest 라는 키를 만들고 dictionary 타입 값으로 gcm_sender_id: '103953800507' 를 추가합니다.

 

 

manifest의 경우 앞서 언급한 YoungwooLee 님의 게시물을 참조해보시면 모든 sender id가 같다고 하십니다.

wikidocs에서도 같은 주장을 하니 벌써 2명의 언급이 있습니다!

 

 

 

 

Service Worker 작성

plugins 폴더 하위sw.js 파일을 생성합니다.

 

import firebase from 'firebase'

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

nuxt.config.js에서 이미 SSR적용을 안하는 상태이기 때문에 따로 처리하지 않았고,

저의 경우 이미 firebase인증을 사용하고 있어서인지 이미 로드가 되어 있기에 위 와 같이 firebase initial을 추가로 작성하지 않았습니다. (가설임)

 

만약 Firebase App named '[DEFAULT]' already exits (app/duplicate-app) 이 출력된다면

import firebase from 'firebase'

if (!firebase.apps.length){
    firebase.initializeApp({
    apiKey: '',  // 아까 Firebase 프로젝트 설정에서 확인한 apiKey
    authDomain: '',  // 아까 Firebase 프로젝트 설정에서 확인한 authDomain
    databaseURL: '',  // 아까 Firebase 프로젝트 설정에서 확인한 databaseURL
    projectId: '',  // 아까 Firebase 프로젝트 설정에서 확인한 projectId
    storageBucket: '',  // 아까 Firebase 프로젝트 설정에서 확인한 storageBucket
    messagingSenderId: '',  // 아까 Firebase 프로젝트 설정에서 확인한 messagingSenderId
    appId: ''  // 아까 Firebase 프로젝트 설정에서 확인한 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.apps를 체크하고 firebase 초기화 해주는 작업을 진행해주시면 됩니다.

소스코드는 역시나 YoungwooLee님의 게시물을 참고하여 작성 했습니다.

 

 

 

 

static 폴더 하위firebase-messaging-sw.js 파일을 생성합니다.

 

// reference: https://firebase.google.com/docs/cloud-messaging/js/receive?hl=ko
importScripts('https://www.gstatic.com/firebasejs/6.3.4/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/6.3.4/firebase-messaging.js');


firebase.initializeApp({
    'messagingSenderId': '', // 아까 프로젝트 설정에서 확인한 messagingSenderId
});

const messaging = firebase.messaging();
messaging.setBackgroundMessageHandler(function(payload){
 
    const notificationTitle = 'Background Message Title';
    const notificationOptions = {
        body: 'Background Message body.',
        icon: '/firebase-logo.png'
    };
    console.log(payload)
 
    return self.registration.showNotification(notificationTitle,
        notificationOptions);
});

위 내용을 작성하는데 초기화 할 때 에는 구글 공식문서를 주석으로 첨부하였는데,

messagingSenderId 만 있어도 된다 캅니다.

 

※ static은 정적파일로 동작하기 때문에 process.env와 같은 내장 함수를 사용할 수 없습니다. 좀 더러운 방법을 써야 하는데 귀찮으니깐 그냥 쓰시죠... 돈 나가는것도 아닌데 메시징아디만 쓰니깐...? 그래서 저거만 쓰게 바꾼건가

 

자 이제 모든 준비가 끝났습니다.

 

 

하지만 테스트는 SSL이 적용된 사이트 혹은 localhost 주소만 가능하니 유의해주세요!

 

 

 

 

 

 

Token으로 한명에게 알림 보내보기

 

브라우저 좌측 상단에 이러한 알림 표시가 이렇게 해서 만들어지는겁니다.

허용을 눌러주시고 개발자도구(F12)를 열어 콘솔을 확인해보면

Notification permission granted.
sw.js?c031:10 The token is:  dhGGgQ9SgYl4iZic817WSi:APA91bE7rMJP_h_UjQ40QfnfqvhKYXneLz6BguZbemoy3cyoLmlXYwFiSutJvOYQlA3XN91PpfEU7ql42WgvsAF8UKxVJe-q5NQVvJ6k3GAhrE3V9xQUjCIcU8wzVJqnIXp_Fx-jy12m

위 처럼 아까 만든 로그가 출력됩니다.

어차피 저 토큰 블로그 예약 글 쓰고 버렸으니 저한테 보내려고하셔도 소용 없습니다 ㅎ__ㅋ

 

 

이제 저 토큰으로 메시지를 보내보겠습니다.

 

 

저는 Python으로 작성하였지만 다른 언어로 nodejs나, Go 등으로 작성하시거나 Postman, PostWoman

 

Postwoman

A free, fast and beautiful API request builder

postwoman.io

을 사용하셔도 무방합니다.

 

 

import json
import requests

token = 'dhGGgQ9SgYl4iZic817WSi:APA91bE7rMJP_h_UjQ40QfnfqvhKYXneLz6BguZbemoy3cyoLmlXYwFiSutJvOYQlA3XN91PpfEU7ql42WgvsAF8UKxVJe-q5NQVvJ6k3GAhrE3V9xQUjCIcU8wzVJqnIXp_Fx-jy12m'
params = {
    "to": token,
    "notification": {
        "title": "yankee 블로그 구독과 공감",
        "body": "유튜브도 구독과 좋아요 잊지마세요!",
        "icon": "https://cdn0.iconfinder.com/data/icons/social-network-9/50/2-512.png",
        "click_action": "https://www.youtube.com/channel/UC9RsPwY9QfPDGD-IMEwLn3Q?view_as=subscriber"
    },
}
key = ''  # 아까 클라우드 메시징 탭 페이지에서 복사한 이전 서버키
headers = {
    'Authorization': f'key={key}',
    'Content-Type': 'application/json; UTF-8',
}

r = requests.post('https://fcm.googleapis.com/fcm/send', data=json.dumps(params), headers=headers)
print(r.json())

콘솔로그에 출력된 토큰 값token 변수로 바꿔주세요

key를 아까 클라우드 메시징 탭 페이지에서 복사한 '이전 서버 키'를 붙여넣어주세요

 

 

알림 예시

위 와 같이 알림이 온다면 성공! 클릭해서 구독과 좋아요 잊지마세요!

 

 

 

 

 

 

다중 Token으로 다수에게 알림 보내보기

import json
import requests

tokens = ['dhGGgQ9SgYl4iZic817WSi:APA91bE7rMJP_h_UjQ40QfnfqvhKYXneLz6BguZbemoy3cyoLmlXYwFiSutJvOYQlA3XN91PpfEU7ql42WgvsAF8UKxVJe-q5NQVvJ6k3GAhrE3V9xQUjCIcU8wzVJqnIXp_Fx-jy12m']
params = {
    "registration_ids": tokens,
    "notification": {
        "title": "yankee 블로그 구독과 공감",
        "body": "유튜브도 구독과 좋아요 잊지마세요!",
        "icon": "https://cdn0.iconfinder.com/data/icons/social-network-9/50/2-512.png",
        "click_action": "https://www.youtube.com/channel/UC9RsPwY9QfPDGD-IMEwLn3Q?view_as=subscriber"
    },
}
key = ''  # 아까 클라우드 메시징 탭 페이지에서 복사한 이전 서버키
headers = {
    'Authorization': f'key={key}',
    'Content-Type': 'application/json; UTF-8',
}

r = requests.post('https://fcm.googleapis.com/fcm/send', data=json.dumps(params), headers=headers)
print(r.json())

그냥 toregistration_ids를 변경하고 tokenString이 아닌 List(배열) 형식으로 작성해서 전송할 토큰들을 적재하고

전송하면 됩니다.

 

 

 

최대 1천명이라고는 하는데 제가 회사 프로젝트에서 테스트했을때는 1천명넘어도 전송됩니다... 흠흠