카테고리 없음

Spring Boot + Nuxt.js 환경에서의 FCM 웹 푸시 구현 (2/2) - Nuxt.js편

mers 2023. 5. 1. 20:55

🪜 1. Nuxt.js - Firebase 설정


1. package.json

  • yarn add firebase
{
	"dependencies": {
			"firebase": "^9.20.0",
	}
}

 

 

2. nuxt.config.js

  • 플러그인을 등록합니다.
export default {
	...
	plugins: [
		{ src: '@/plugins/firebase' },
	],
},

 

 

 

3.  plugins/firebase.js

import { initializeApp, getApps } from 'firebase/app';
import { getMessaging } from 'firebase/messaging'

const firebaseConfig = {
/* FCM 발급받은 키 입력 */ 
    apiKey: "",
    authDomain: "",
    projectId: "", 
    storageBucket: "",
    messagingSenderId: "",
    appId: "",
    measurementId: ""
};

const apps = getApps()

//1
// const app = !apps.length ? initializeApp(firebaseConfig) : apps[0]
//
// export const messaging = getMessaging(app)

//2
const app = !apps.length ? initializeApp(firebaseConfig) : apps[0]

let messaging = null
if (process.client) {
  messaging = getMessaging(app)
}

export { messaging }

 

 

4. static/firebase-messaging-sw.js

  • importScripts에서 9버전 이전이라면 compact를 제외하고 입력합니다.
  • FCM 알림이 오면 백그라운드에서의 service worker 이 받아서 표시합니다.
importScripts(
    'https://www.gstatic.com/firebasejs/9.20.0/firebase-app-compat.js'
)
importScripts(
    'https://www.gstatic.com/firebasejs/9.20.0/firebase-messaging-compat.js'
)
firebase.initializeApp({
    /* FCM 발급받은 키 입력 */ 
    apiKey: "",
    authDomain: "",
    projectId: "", 
    storageBucket: "",
    messagingSenderId: "",
    appId: "",
    measurementId: ""
})

// Retrieve an instance of Firebase Messaging so that it can handle background
// messages.
const messaging = firebase.messaging()

// [background] push notification event listener
messaging.onBackgroundMessage((payload) => {
    // const channel = new BroadcastChannel('sw-message')
    // channel.postMessage(payload.notification)

    console.log('[firebase-messaging-sw.js] Received background message ', payload);
    // Customize notification here
    const notificationTitle = payload.notification.title;
    const notificationOptions = {
        body: payload.notification.body,
        // icon: '/firebase-logo.png'
    };

    self.registration.showNotification(notificationTitle, notificationOptions);
});

 

 

 

5. login.vue (예제)

  • 아래처럼 로그인 시에 구독하도록 backend에 api를 쏘고 로그아웃 시 구독 해제 하도록 api 요청할 수 있습니다.
<template>
    
</template>
<script>
import { getAuth, signInAnonymously } from 'firebase/auth'
import { getMessaging, onMessage, getToken } from 'firebase/messaging'
import { messaging } from '../plugins/firebase.js'

export default {
    data () {
        return {
            idToken: '',
            vapidKey: /* FCM에 있는 vapidKey 입력 */'',
    },
    mounted () {
        this.authenticate();

        const messaging = getMessaging();
        
        // foreGround 에서 알림수신 
        onMessage(messaging, (payload) => {
            console.log('Message received. ', payload);
        });
    },
    methods: {
        // 브라우저 Window 팝업
        fcmNotify(title, msg) {
            let options = {
                body: msg
            }
            let n = new Notification(title, options);

            setTimeout(n.close.bind(n), 3000);
        },
        async authenticate() {
            await signInAnonymously(getAuth())
            await this.activate()
        },
        async activate() {
            const token = await getToken(messaging, {
                vapidKey: this.vapidKey
            })
        
            if (token) {
                this.idToken = token;
                console.log('token -> ', token);
            } else {
                console.log('No Instance ID token available. Request permission to generate one.')
            }
        },

        userLogin ( result ) {

            // fcm 구독요청 함수
            if (!ObjectUtil.isEmpty(this.idToken))
                this.$axios.voPost('/api/fcm/subscribe', {TOKEN: this.idToken});
        }
    },
}
</script>