Search code examples
javascriptvue.jspush-notificationweb-push

VuePWA / Web Push: My service-worker doesn't ask the user to give permission


I did the Google Introduction to Push notification code lab, and now I want to adapt my VueJS PWA to use Push notification !

I must use WorkBox since I use a VueJS PWA and my only issue is that the service-worker never ask the user to grant notification permissions.

Here is the sw.js's code :

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

import Subscription from "@/api/Subscription";

// Internal helper 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 store 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);
        });
  }
}

I know it's working and registered since I see it in the console and since I get the Push in the console :

enter image description here enter image description here

But I don't know why it doesn't ask for the permissions...

Someone can help me ?


Solution

  • Thank you to @lissy93 for the help but I managed to fix it by adding the following code to my chatbot.vue :

    import { subscribeUser } from "../helpers/subscriptionHandler";
    
    ...
      mounted() {
        subscribeUser();
      },