How to add FCM (Firebase Cloud Messaging) to VueJS

vbanditv

Fima Taf

Posted on March 8, 2021

How to add FCM (Firebase Cloud Messaging) to VueJS

Lately I had a task to implement FCM (Firebase Cloud Messaging) to a vue application I am working on, and I've found out that there are few guides but they didn't helped me too much because FCM's API, vue cli and vue it self were updated since then, so I've decided to write down a small and updated guide for it.

Step 1 - Add the service worker file

The first thing that we need to do is to add the service worker file firebase-messaging-sw.js to the public folder (It's important to use this file name because firebase will look for this file with that specific name, it can be changed tough but not in this guide - sorry).
(If you are not familiar with the words 'service worker' you can learn more about it Here or Here)

//firebase-messaging-sw.js

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

var firebaseConfig = {
  apiKey: <API-KEY>,
  authDomain: <AUTH-DOMAIN>,
  projectId: <PROJECT-ID>,
  storageBucket: <STORAGE-BUCKET>,
  messagingSenderId: <MESSAGING-SENDER-ID>,
  appId: <APP-ID>,
  measurementId: <MEASUREMENT-ID>
}

const app = firebase.initializeApp(firebaseConfig)
Enter fullscreen mode Exit fullscreen mode

Replace the config json above with the one you got from firebase
Go to your project home page at firebase -> Press on the Settings icon -> click 'Project Settings' -> Scroll down -> firebaseConfig object

Step 2 - Register the service worker

The next step is to register the service worker.
We have few ways of doing that:

* If you prefer using firebase package jump to Step 3.

* Using vue cli's PWA plugin

If you've created your application through vue cli (v3+) and you've added the PWA support option (or added this plugin manually after the installation) you can register the service worker with registerServiceWorker.js file as follows:

//registerServiceWorker.js

import { register } from 'register-service-worker'

register('firebase-messaging-sw.js')
Enter fullscreen mode Exit fullscreen mode

You can learn more about the above plugin and its events Here

* Using vanilla JS

If you prefer to register the service worker using only JS, you can add the following code (anywhere in your application):

if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('firebase-messaging-sw.js')
    .then(reg => {
      console.log(`Service Worker Registration (Scope: ${reg.scope})`);
    })
    .catch(error => {
      const msg = `Service Worker Error (${error})`;
      console.error(msg);
    });
} else {
  // happens when the app isn't served over HTTPS or if the browser doesn't support service workers
  console.warn('Service Worker not available');
}
Enter fullscreen mode Exit fullscreen mode

Step 3 - Using firebase module

Another way to register the service worker and subscribe to FCM is by installing the firebase package.
npm install firebase
After you've installed the package, create a file called firebase.js (or any other name you want) and add the following:

//firebase.js

import firebase from 'firebase/app'
import 'firebase/firebase-messaging'

var firebaseConfig = {
  apiKey: <API-KEY>,
  authDomain: <AUTH-DOMAIN>,
  projectId: <PROJECT-ID>,
  storageBucket: <STORAGE-BUCKET>,
  messagingSenderId: <MESSAGING-SENDER-ID>,
  appId: <APP-ID>,
  measurementId: <MEASUREMENT-ID>
}

firebase.initializeApp(firebaseConfig)

export default firebase.messaging()
Enter fullscreen mode Exit fullscreen mode

Why do I need to instanciate firebase again? I already did it on step 1...

Because the service worker is running on another thread and not on the main one, therefor we cannot pass the instance to our main application.

Add FCM in vue 2

To add FCM as a global in your vue 2 application go to your main.js file and add the following:

//main.js

...
import firebaseMessaging from './firebase'

Vue.prototype.$messaging = firebaseMessaging

new Vue({
...
Enter fullscreen mode Exit fullscreen mode

Now you can access FCM instance everywhere in your application by calling this.$messaging.

Add FCM in vue 3

Add as a global

You can add FCM as a global in vue 3 but then it won't be accessible in composition's API setup() method.

//main.js

...
import firebaseMessaging from './firebase'

const app = createApp(App)

app.config.globalProperties.$messaging = firebaseMessaging

app.mount('#app')
Enter fullscreen mode Exit fullscreen mode

Now you can call it in every component:

//RandomComponent.vue

...
  mounted () {
    console.log('Firebase cloud messaging object', this.$messaging)
  }
...
Enter fullscreen mode Exit fullscreen mode

Use Provide/Inject

Another way that vue 3 is providing to pass data is the Provide/Inject feature. (You can learn more about it Here)
In your App.vue (or any other component you want the 'Super Parent' to be) add the following:

//App.vue

...
<script>
import { provide } from 'vue'
import firebaseMessaging from './firebase'

export default {
  //options api
  provide: {
    messaging: firebaseMessaging
  }
  //composition api
  setup() {
    provide('messaging', firebaseMessaging)
  }
}
</script>
...
Enter fullscreen mode Exit fullscreen mode

And Now you can call it by injecting it into any child component you want, for example:

//RandomChildComponent.vue

...
<script>
import { inject } from 'vue'

export default {
  //options api
  inject: ['messaging'],
  mounted () {
    console.log('Firebase cloud messaging object', this.$messaging)
  }
  //composition api
  setup() {
    const messaging = inject('messaging')

    console.log('Firebase cloud messaging object', messaging)
  }
}
</script>
...
Enter fullscreen mode Exit fullscreen mode

Step 4 - Subscribe

After the service worker has been registered we can subscribe our client to FCM by calling the getToken() function.
Go back to firebase-messaging-sw.js (if you used step 2) or call firebase's messaging object (if you used step 3) and add the following code:

...
//firebase-messaging-sw.js (step 2)
app.messaging().getToken({ vapidKey: <KEY> })

//RandomChildComponent.vue (step 3)
messaging.getToken({ vapidKey: <KEY> })
...
Enter fullscreen mode Exit fullscreen mode

To get the vapidKey go to firebase console:

Go to your project home page at firebase -> Press on the Settings icon -> click 'Project Settings' -> 'Cloud Messaging' tab -> 'Web configuration' > 'Web Push certificates'

  • In case you want to get the specific token of each client you can add the following to your getToken() function:
app.messaging().getToken({ vapidKey: <KEY> })
.then((currentToken) => {
  if (currentToken) {
    console.log('client token', currentToken)
  } else {
    console.log('No registration token available. Request permission to generate one.');
  }
}).catch((err) => {
  console.log('An error occurred while retrieving token. ', err);
})
Enter fullscreen mode Exit fullscreen mode
In case you used step 3 (firebase package) getToken() method will also register the service worker for you.

The getToken() function will subscribe to FCM and since this moment your client will get push notification from FCM. yey :)

Hope it helped you somehow, enjoy :)

💖 💪 🙅 🚩
vbanditv
Fima Taf

Posted on March 8, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related