Open a custom url when clicking on a web push notification

24,911

Solution 1

From the Webpush (with a payload) documentation, it seems that you should put all your data into the message, using the JSON.stringify() method, and retrieve it in the service worker with JSON.parse().

Server:

Webpush.payload_send({
  message:JSON.stringify({
    message: notification.message,
    url: notification.url,
    id: notification.id,
  }),
  endpoint: endpoint,
  p256dh: p256dh_key,
  vapid: vapid_keys,
  ttl: 24 * 60 * 60,
  auth: auth_key,
})

Client:

 event.waitUntil(
   self.registration.showNotification(title, {
   body: "New push notification",
   icon: "/images/[email protected]",
   tag:  "push-notification-tag",
   data: {
     url: JSON.parse(event.message).url
   }
})

Solution 2

Custom data comes in event.notification object not in event directly(in notificationclick). So if you want to fetch the custom data variable in notificationclick function, then you should do it like this :)

self.addEventListener('notificationclick', function(event) {
  event.notification.close();
  event.waitUntil(
    clients.openWindow(event.notification.data.url + "?notification_id=" + event.notification.data.id)
  );
})

Solution 3

For Webpush Ruby Gem, with some modifications, here's what worked for me:

Webpush.payload_send(
  endpoint: user.push_subscription.endpoint,
  message: {
    message: "A new service request is created",
    id: service_request.request_number,
    url: "https://google.com/"
  }.to_json,
  p256dh: user.push_subscription.key,
  auth: user.push_subscription.auth_key,
  ttl: 24 * 60 * 60,
  vapid: {
    subject: 'A Push Notification',
    public_key: ENV['VAPID_PUBLIC_KEY'],
    private_key: ENV['VAPID_PRIVATE_KEY']
  }
)

Where:

  • user.push_subscription.endpoint is a method defined in PushSubscription model to return the endpoint
  • user.push_subscription.key, user.push_subscription.auth_key are again methods defined in the same model

Inside /serviceworker.js.erb

self.addEventListener("push", (event) => {
  let response = event.data && event.data.text();
  let title = JSON.parse(response).message;
  let body = JSON.parse(response).id;
  let icon = '/assets/logo-blue-120x120.jpg';

  event.waitUntil(
    self.registration.showNotification(title, { body, icon, data: { url: JSON.parse(response).url } })
  )
});

self.addEventListener('notificationclick', function(event) {
  event.notification.close();
  event.waitUntil(
    clients.openWindow(event.notification.data.url)
  );
});
Share:
24,911
BananaNeil
Author by

BananaNeil

I am a lion, rawr.

Updated on August 21, 2020

Comments

  • BananaNeil
    BananaNeil over 3 years

    I am implementing the Webpush ruby gem to send push notifications to users of my website.

    Server code:

      Webpush.payload_send({
          message: notification.message,
          url: notification.url,  # I can't figure out how to access this key
          id: notification.id,    # or this key from the service worker
          endpoint: endpoint,
          p256dh: p256dh_key,
          vapid: vapid_keys,
          ttl: 24 * 60 * 60,
          auth: auth_key,
        })
    

    I have a service worker set up on the client side to show the notification and make it clickable.

    self.addEventListener("push", function (event) {
      var title = (event.data && event.data.text()) || "New Message";
    
      event.waitUntil(
        self.registration.showNotification(title, {
          body: "New push notification",
          icon: "/images/[email protected]",
          tag:  "push-notification-tag",
          data: {
            url: event.data.url, // This is returning null
            id: event.data.id // And this is returning null
          }
        })
      )
    });
    
    self.addEventListener('notificationclick', function(event) {
      event.notification.close();
      event.waitUntil(
        clients.openWindow(event.data.url + "?notification_id=" + event.data.id)
      );
    })
    

    It is all working fine, except the custom keys (url, id) that I am passing through are not accessible from within the service worker.

    Does anyone know how to pass custom data through the WebPush gem?