Notification issues in Vue with Firebase Cloud Messaging while in foreground

I have been working on implementing FCM in my Vue PWA application. I have successfully configured background notifications, but I am facing issues with handling notifications when the app is open. Here is the code I am using.

src/App.vue

import firebase from './plugins/firebase'

export default {
  // Other content...

  methods: {
    prepareFcm () {
      var messaging = firebase.messaging()
      messaging.usePublicVapidKey(this.$store.state.fcm.vapidKey)
      messaging.getToken().then(async fcmToken => {
        this.$store.commit('fcm/setToken', fcmToken)
        messaging.onMessage(payload => {
          window.alert(payload)
        })
      }).catch(e => {
        this.$store.commit('toast/setError', 'An error occurred while processing push notification.')
      })
    }
  },

  mounted () {
    this.prepareFcm()
  }
}

public/firebase-messaging-sw.js

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

firebase.initializeApp({
  messagingSenderId: '123456789'
})

const messaging = firebase.messaging()

messaging.setBackgroundMessageHandler(function (payload) {
  return self.registration.showNotification(payload)
})

src/plugins/firebase.js

import firebase from '@firebase/app'
import '@firebase/messaging'
// import other firebase libraries...

const firebaseConfig = {
  apiKey: '...',
  authDomain: '...',
  databaseURL: '...',
  projectId: '...',
  storageBucket: '...',
  messagingSenderId: '123456789',
  appId: '...'
}

firebase.initializeApp(firebaseConfig)

export default firebase

What could be the issue with my setup?

Answer №1

I came across a solution in a previous question and answer on StackOverflow (although I seem to have lost the link).

It turns out that using Firebase API version 7.8.0 is necessary instead of the previously recommended 5.5.6. Therefore, the initial lines in public/firebase-messaging-sw.js should be adjusted as follows:

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

Answer №2

I encountered the same issue recently. The problem was that the firebase version specified in my "package.json" file did not match the version imported in my "firebase-messaging-sw.js" file using importScripts. Once I aligned both versions to be the same as the one in "package.json", the issue was resolved.

Initial setup

 **"package.json"**
 
 "firebase": "^8.2.1",
 
  **"firebase-messaging-sw.js"**

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

Corrected setup

 **"package.json"**

 "firebase": "^8.2.1",

 **"firebase-messaging-sw.js"**

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

Answer №3

I encountered a discrepancy between the version on my package.json (8.2.1) and the actual SDK_VERSION (8.0.1)

Once I updated the service-workers to match the correct version, everything worked smoothly.

Answer №4

Tackling firebase push notifications in Vue 3 (with Vite) was a bit of a challenge for me, especially with PWA support enabled through vite-plugin-pwa. It often felt like navigating blindly through uncharted territory. Despite successfully setting up PWA support, I encountered some persistent issues:

  • Notifications were received in the background but not in the foreground.
  • Background notifications appeared duplicated at times.

Below is my complete setup utilizing the latest version of Firebase (9.12.1) at the time of writing this post:

// Store this file as firebase-messaging-sw.js in public folder
   
importScripts(
      "https://www.gstatic.com/firebasejs/9.12.1/firebase-app-compat.js"
    );
importScripts(
      "https://www.gstatic.com/firebasejs/9.12.1/firebase-messaging-compat.js"
    );
// Initialize Firebase
firebase.initializeApp({
  apiKey: "",
  authDomain: "",
  projectId: "",
  storageBucket: "",
  messagingSenderId: "",
  appId: "",
  measurementId: "",
});
const messaging = firebase.messaging();

    
messaging.onBackgroundMessage(function (payload) {
// Customize notification here
  const notificationTitle = payload.notification.title;
  const notificationOptions = {
  body: payload.notification.body,
  icon: "/icon.png",
};

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

Suggestions online placed the onBackgroundMessage function in the service worker, but after experimenting and commenting it out, the issue of duplicate notifications seemed to be resolved.

Next, in a file named firebase.js, tokens are retrieved along with listening for foreground notifications:

// Place this firebase.js file alongside main.js
    
import firebase from "firebase/compat/app";
import { getMessaging } from "firebase/messaging";
    
const firebaseConfig = {
  apiKey: "",
  authDomain: "",
  projectId: "",
  storageBucket: "",
  messagingSenderId: "",
  appId: "",
  measurementId: "",
};
    
const app = firebase.initializeApp(firebaseConfig);
export default getMessaging(app);

In main.js:

import App from "./App.vue";
import firebaseMessaging from "./firebase";

const app = createApp(App)
app.config.globalProperties.$messaging = firebaseMessaging; //register as a global property

Lastly, in App.vue (or any desired location for token retrieval and server-side transfer):

import {getToken, onMessage} from "firebase/messaging";

export default {
  mounted() {
    getToken(this.$messaging, {
      vapidKey:
        "XXX-XXX",
    })
      .then((currentToken) => {
        if (currentToken) {
          console.log("client token", currentToken);
          onMessage(this.$messaging, (payload) => {
            console.log("Message received. ", payload);
          });
          
          //send token to server-side
        } else {
          console.log(
            "No registration token available. Request permission to generate one"
          );
        }
      })
      .catch((err) => {
        console.log("An error occurred while retrieving token.", err);
      });
  }
}

Remember to include the necessary vapidKey. It may take some trial and error, but the solution worked smoothly in the end.

As for designing the appearance of foreground notifications, I have refrained from providing an opinion and simply logged the payload. Feel free to customize it to your liking.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Ways to gradually reveal all elements within a header section

Is there a way to gradually reveal all the components in my header once the window has finished loading by utilizing jQuery's fadeIn function? Below is the pertinent code snippet: HTML <div class="banner"> <header class="header"> < ...

I am looking to retrieve data from the Graph API JSON and gradually refine my search to achieve successful

I am looking to retrieve data from the "fb_page_categories" endpoint, which provides an array of categories a page can be categorized under. The format for this request is as follows: GET graph.facebook.com /fb_page_categories? Once this request is mad ...

retrieving data from GET variables and sending to a PHP array

Is there a way to retrieve form variables and store them in an array in memory without reloading the page? I'm not very experienced with this, so any guidance would be appreciated. My goal is to update a JSON file using PHP based on form inputs. JSON ...

Using Ajax to update multiple text field rows with unique values

I have a question regarding utilizing Ajax to update the second text field based on the input from the first text field. I am looking to create multiple rows using a for loop, with each row having its own set of values. HTML <form style="text-align:c ...

Concurrent Accordion and Color Transformation Animations

I am currently utilizing jQuery version 2.0.3 and jQuery UI version 1.10.3, specifically using the accordion feature. I am attempting to modify the color of the accordion panels as they open and close by implementing the following code: $(".main-content") ...

Error in ReactJS: Trying to access property 'items' of an undefined object

I've been diving into ReactJS, but I've hit a roadblock with this perplexing error. My goal is to update the parent's items array state from its child component. To achieve this, I attempted to pass the addItem function as a prop to the chi ...

Executing a file function from another within a module function in ReactJS

I need to utilize the functions that are defined in the apiGet.js file: export let apiGet = () => { return 'File One'; } These functions are being called in another module called brand.js. Here is the code snippet: require("../action ...

Create a validation rule in yup that depends on an external condition

I am currently attempting to set a condition based on a prop that is passed to a VueJS object. After researching some solutions, I noticed they all focus on using .when. However, .when is typically used when you need to establish a condition based on anot ...

Names picked at random and presented in the innerHTML

I am currently working on a project that involves displaying random names from an array in a text area named "textbox". Currently, I am using math.random() to pick a name randomly, but it only generates a new random name when the page is reloaded. How ca ...

Can a props be retrieved and passed as an argument to a function?

My goal is to retrieve a prop from MapsStateToProps using react-redux's connect and then pass it to a child component. This prop serves as an argument for a function, which in turn returns something that becomes the state of the child component. Alth ...

What sets apart Selenium's mouseMove() function from the physical movement of a mouse?

Imagine I have element A and element B on a webpage. Using tools like Selenium or PhantomJS, I can manipulate the mouse via coordinates. By identifying the position of element A (a link) and element B (a submit button), I can create a bezier curve or mimi ...

Adjusting the X-axis in Highstock: Tips and Tricks

Is there a way to adjust the X axis on this chart? My goal is to shift it so that it only covers half of the width, leaving the other half blank for future plotlines. Any suggestions on how to achieve this? Thanks! :) ...

Using single page anchor tags in Next.js to toggle content visibility

The Issue Currently working on a project using Next.js and facing a challenge: needing to hide or replace content based on the selected category without reloading the page or navigating to another route. Furthermore, ensuring that when the page is reloade ...

Automatic placement of the cursor at the left end of the username field in the registration form is required

Hey there! I'm looking to customize the registration form on my WordPress website so that when a user clicks on any field, such as the username field, the cursor automatically moves to the left end of that field and the keyboard switches to ENG-US. ...

Error: The function jQuery(...).hexColorPicker does not exist

I am attempting to utilize a color-picker jQuery plugin. Below is a screenshot of the JavaScript file: https://i.stack.imgur.com/ovRjx.png Here is the code I am using to initialize it: <script type="text/javascript> jQuery(function(){ ...

Executing a script that has been inserted into the page post-loading

I'm facing an issue where the script tag at the bottom of my project is not being executed after adding new pages later on. Main const fetch = (url, call) => { var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if ...

Preserving client-side page state during page reloads in angular.js apps

I am currently developing a Single Page application using angular.js and I have encountered an issue that I am struggling to resolve. When performing a full page refresh in an angular app, how can we verify if the user still has a valid session? While Sta ...

How can the client be informed about the ongoing processing of the request by the servlet?

In my web application, I have JS/jQuery on the front end and servlets on the back end. When making a request to a servlet, it performs multiple tasks in one call (such as executing a shell script that runs various Python scripts). My main query is whether ...

Unable to access Bootstrap dropdown menu after initial ajax form submission

I am encountering an issue with a dropdown menu on my webpage, specifically within the manager.php file. Please excuse any formatting discrepancies as I am using Bootstrap: <!-- Bootstrap --> <script type="text/javascript" src="https://netdna ...

Node.js project is set up globally on personal system

Introduction I'm diving into the world of Node.js and eager to learn. NPM has been a game changer for me as I can easily install packages globally and utilize them as standalone applications accessible from anywhere on my system. To my surprise, thi ...