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)
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')
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');
}
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()
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({
...
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')
Now you can call it in every component:
//RandomComponent.vue
...
mounted () {
console.log('Firebase cloud messaging object', this.$messaging)
}
...
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>
...
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>
...
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> })
...
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);
})
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 :)
Top comments (17)
Thanks a lot!
I could be able to complete all the steps successfully following this article.
I am getting an error
Hi,
I'm getting this too - on build.
Do you remember how you fixed it - assuming you did :)
Thanks
This is due to a firebase npm package version 9 bug.
Solution: steps-
Are you trying to install firebase npm package? If you do, then what is the version ?
How can i get access to the generated "currentToken" in vue ?
Hey,
You can call the
getToken()
function again - you will get the registered token.Thanks a lot!
register(
${process.env.BASE_URL}firebase-messaging-sw.js
)Hi Fima!
How to post currentToken to some API by axios?
I cannot use import statement outside vue module!
Hey,
I guess you are trying to send the request from the service worker and not from the app itself, as far as I know you can't access
axios
inside service workers - but you can usefetch
instead:Hello,
Is it necessary to put firebase.js in a specific folder on step 3?
Can you give me the advice to tell me should put this file (firebase.js) in which folder?
Hey, you can place the firebase.js file where-ever you want, you can even place the content of the file inside main.js and delete firebase.js.
Step3, firebase.js code throw an error like this, why?
i am getting this error when i get vapidKey
i used step 3
How to subscribe to specific topics with this approach bro? Thanks in advance.
it is necessary to import something to use messaging.getToken in Step 4 ?
Yes, you need to import firebaseMessaging from the src/firebase.js file. Then you can use it like firebaseMessaging.getToken()