Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Angulars Service Worker - "beforePushNotification" #55641

Open
Flo0806 opened this issue May 2, 2024 · 1 comment
Open

Angulars Service Worker - "beforePushNotification" #55641

Flo0806 opened this issue May 2, 2024 · 1 comment
Labels
area: service-worker Issues related to the @angular/service-worker package
Milestone

Comments

@Flo0806
Copy link

Flo0806 commented May 2, 2024

Which @angular/* package(s) are relevant/related to the feature request?

Angular 17.3.x and @angular/pwa

Description

Angulars ngsw-worker.js shows notification at any time a "push" event occurs. However, receiving push notifications when the app is open and in the foreground is not a good user experience. Angular's service worker does not offer a direct way to determine whether a notification should finally be displayed or not. The "onPush" method cannot be overwritten, at most it can be extended - which does not lead to the desired result.

I tried things with a custom service worker like this:

self.addEventListener("push", (event) => {
  console.log("Push event detected, but notifications are suppressed.");
  event.preventDefault();
  event.stopPropagation();

  event.waitUntil(
    (async function () {

      console.log("Received push", event.data.json());
      event.data.json().notification.title = null;

      return;
    })()
  );
});

importScripts("./ngsw-worker.js");

but without success (It doesn't matter whether importScripts is at the top or at the bottom)

Proposed solution

A option to set, or a optional function which will return a boolean, like this:

this.swPush.beforePushNotification = () => { return false; }

Alternatives considered

A way to override functions like "onPush" in the Service Worker itself.

@Flo0806
Copy link
Author

Flo0806 commented May 3, 2024

In the end we can always add our own service worker. But that was not my goal. I have found a solution - it's not the best way to go, but it works:

self.addEventListener("push", (event) => {
  event.preventDefault();
  event.stopPropagation();
  event.stopImmediatePropagation();
  if (!event.data) {
    return;
  }
  event.waitUntil(
    (async (mySelf) => {
      const windowClients = await mySelf.clients.matchAll({ type: "window" });
      if (!windowClients || !windowClients[0]) return;

      const client = windowClients[0];
      
      if (client && client .visibilityState !== "visible") {
        await handlePush(event.data.json());
      }
    })(self)
  );
});

async function broadcast(msg) {
  const clients = await self.clients.matchAll();
  clients.forEach((client) => {
    client.postMessage(msg);
  });
}

async function handlePush(data) {
  var NOTIFICATION_OPTION_NAMES = [
    "actions",
    "badge",
    "body",
    "data",
    "dir",
    "icon",
    "image",
    "lang",
    "renotify",
    "requireInteraction",
    "silent",
    "tag",
    "timestamp",
    "title",
    "vibrate",
  ];

  await broadcast({
    type: "PUSH",
    data,
  });
  if (!data.notification || !data.notification.title) {
    return;
  }
  const desc = data.notification;
  let options = {};
  NOTIFICATION_OPTION_NAMES.filter((name) => desc.hasOwnProperty(name)).forEach(
    (name) => (options[name] = desc[name])
  );
  await self.registration.showNotification(desc["title"], options);
}

importScripts("./ngsw-worker.js");

@pkozlowski-opensource pkozlowski-opensource added the area: service-worker Issues related to the @angular/service-worker package label May 16, 2024
@ngbot ngbot bot added this to the needsTriage milestone May 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: service-worker Issues related to the @angular/service-worker package
Projects
None yet
Development

No branches or pull requests

2 participants