Issue: My VuePWA/Web Push service worker is not prompting the user to grant permission

After completing the Google Introduction to Push notification code lab, I am eager to incorporate Push notifications into my VueJS PWA. The only hurdle I face is that the service worker fails to prompt users for notification permissions.

The code snippet from sw.js is as follows:

/**
 * This helper handles the notification subscriptions and unsubscriptions
 */

import Subscription from "@/api/Subscription";

// Internal function to convert a BASE64 encoded string to UINT8
function urlBase64ToUint8Array(base64String) {
  console.log("base64");
  const padding = "=".repeat((4 - (base64String.length % 4)) % 4);
  const base64 = (base64String + padding).replace(/-/g, "+").replace(/_/g, "/");

  const rawData = atob(base64);
  const outputArray = new Uint8Array(rawData.length);

  for (let i = 0; i < rawData.length; ++i) {
    outputArray[i] = rawData.charCodeAt(i);
  }

  return outputArray;
}

function askBrowserPermission() {
  console.log("ask");
  return new Promise(function (resolve, reject) {
    if ("Notification" in window) {
      const permissionResult = Notification.requestPermission(function (result) {
        resolve(result);
      });

      if (permissionResult) {
        permissionResult.then(resolve, reject);
      }
    } else {
      throw new Error("This browser does not support push notifications");
    }
  });
}

// Create a subscription and save it on the server
function createSubscription(registration) {
  console.log("createSub");
  const applicationServerKey = urlBase64ToUint8Array(
      process.env.VUE_APP_PUBLIC_VAPID_KEY_BASE64
  );
  const options = {
    applicationServerKey,
    userVisibleOnly: true,
  };
  registration.pushManager.subscribe(options).then((newSubscription) => {
    // SEND TO THE SERVER THE REQUEST
    Subscription.post(newSubscription).catch(error => {
      unsubscribeUser()
      console.error(error)
    });
  });
}

export function subscribeUser() {
  console.log("subUser");
  if ("serviceWorker" in navigator) {
    navigator.serviceWorker.ready
        .then(function (registration) {
          askBrowserPermission()
              .then((result) => {
                if (result === "granted") {
                  // Check if user has already subscription or not
                  registration.pushManager.getSubscription().then((sub) => {
                    if (sub === null) {
                      createSubscription(registration);
                    }
                  });
                } else {
                  // Notify user that his preference setting does not correspond to this decision
                  // Option to change preference
                }
              })
              .catch((error) => {
                console.error(error);
              });
        })
        .catch(function (err) {
          console.error("Service Worker registration failed: ", err);
        });
  }
}

export function unsubscribeUser() {
  console.log("unsubuser");
  if ("serviceWorker" in navigator) {
    navigator.serviceWorker.ready
        .then(function (registration) {
          registration.pushManager.getSubscription().then((sub) => {
            if (sub !== null) {
              sub.unsubscribe().then((result) => {
                if (!result) {
                  console.error("Encountered a problem unsubscribing the user");
                }
              });
            } else {
              // Nothing to do no subscription was found
            }
          });
        })
        .catch(function (err) {
          console.error("Service Worker registration failed: ", err);
        });
  }
}

Even though the console displays notifications and confirms registration, the permission dialog never shows up...

Any assistance would be highly appreciated!

Answer №1

Big thanks to @lissy93 for the assistance! I was able to resolve the issue by incorporating the code snippet below into my chatbot.vue:

import { subscribeUser } from "../helpers/subscriptionHandler";

...
  mounted() {
    subscribeUser();
  },

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

There was a 401 HTTP error encountered when trying to make a basic auth GET request from Axios

Currently, I am developing an API utilizing Flask (with flask-restful extension) and a frontend application using Vue.js. Both applications are running on localhost at the moment. flask: 127.0.0.1:5000, vue: localhost:8080/ To make requests to the API, I ...

Which is more effective: Layering multiple canvases in the DOM or consolidating all drawing on a single canvas?

In my previous projects, I have had experience working with layered canvases. While some of my colleagues swear by this approach, I find myself skeptical about its effectiveness. My primary concerns are: If multiple canvases are layered and one undergoes ...

What causes jQuery's .width() method to switch from returning the CSS-set percentage to the pixel width after a window resize?

After exhaustively console logging my code, I have finally identified the issue: I am attempting to determine the pixel width of some nested divs, and everywhere I look suggests that jQuery's .width() method should solve the problem. The complication ...

What's the best way to mount multiple Vue Single File Components?

Suppose you have an index.js file structured like this: new Vue({ el: '#app', components: { 'hello': Hello, 'counter': Counter, 'goodbye': GoodBye } }); And your index.html file ...

Stop the initial expansion of the first accordion with JavaScript on page load

I have a simple accordion created using only pure javascript without jQuery and Pure CSS. Everything is functioning correctly, but the problem I am facing is that the first accordion is automatically expanded when the page loads. I have tried various metho ...

Encountering difficulties while implementing the AJAX request with the Giphy API

I am just getting started with jQuery and JavaScript. My goal with the ajax or get method is to input any keyword (like maine coon, for example), hit submit, and then see a page full of maine coon gifs. The API code I am working with is from Giphy. func ...

Is there a way to dynamically update the polyline on the map when I drag a marker to change the path, removing the previous one in the process?

I'm still fairly new to working with Javascript and the Google Maps API. I've come across various solutions to a similar issue that I'm facing, but none of them seem to work for my specific code. I'm starting to question whether the pol ...

Issue with inconsistent functionality of Socket.io

I've encountered an issue while working with multiple modules - specifically, socket.io is not functioning consistently... We have successfully implemented several 'routes' in Socket.io that work flawlessly every time! However, we are now ...

What is the best way to calculate the number of days that have passed since a certain

Hey there, I've got this 10 Dec, 2019T14:07:21 date format from the backend. My goal is to determine how many days ago it was. For example, today is the 20th, so if the date is today's date, it should show as 0 days ago. ...

What could be the reason behind the login button not triggering the console message display?

I've decided to delve into web server development on my own and have been tweaking a GitHub repository for ExpressJS with Typescript that I stumbled upon. My initial goal is simple - just to have something displayed on the console when I click the log ...

Organizing NodeJS modules in a way that mirrors Maven's groupId concept

I am making the switch to NodeJS after working extensively with Maven. In Maven, we are familiar with the groupId and artifactID, as well as the package name when starting a new project. However, in NodeJS, I only see a module name. The concept of groupI ...

Controlling data tables with knockout.js

I have successfully integrated an API in knockout.js, but I am facing an issue with displaying the amount based on accounting principles. My table definition includes columns for id, name, debit, credit, and amount. Since not all amounts fall under debit o ...

Tips for retrieving all JavaScript source links from a website URL during page download

Is there a way to determine if a website is using a specific online JavaScript source, such as fontawesome? Some sources may only become apparent once they are actually loaded, rather than being visible in the website's source HTML. I attempted to us ...

Buffering ceases on the video

I am experiencing an issue with 4 videos and a preloader, which should hide once all the videos are fully buffered. <div id="preload"> <h1> Download... </h1> </div> <video preload="auto" class= ...

Experiencing difficulty navigating JSON objects

I am facing an issue with a JSON structure that has the following format: [ { "coordinates": [ 75.71027043, 26.88661823 ] }, { "coordinates": [ 75.71027043, 26.88661823 ...

Optimizing Angular's ng-repeat for efficient updates by restricting the watch functionality to the relevant iteration

My task involves creating a table where users can edit certain fields in each row, which will impact other fields within the same row. Due to this requirement, I cannot use bind-once for all the rendered data. To address this issue, I attempted using the ...

Error: a is missing in the Google Maps configuration

I'm looking to integrate Google Maps into my program, but I've encountered an error stating that 'a is null' when using a variable in the Google Maps API. Below is my current implementation: //Creates a new center location for the goog ...

if and elsif JSON with Angular

Currently, I am working on completing a task within our project. To provide more context, I have a field with items that I must select. Once I choose an item, another field appears in which I must select additional elements. These elements need to be sen ...

Troubleshooting Intel Edison application update issues

After setting up the IoT XDK, I decided to try out the blink example. Excitedly, I saw that the LED on pin 13 was blinking just as expected! But when I attempted to change the interval from 1000ms to 100ms and 3000ms, there was no difference in the blinkin ...

Display or conceal image description upon mouseover

Attempting to create a portfolio page with images and implementing jquery to display and animate the captions on hover. However, when I attempted to do so, it didn't work with the code I have. The code snippet is provided below for reference. Snippet ...