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?
How to Add the In-App Link in a Push Notification. After all pending changes are made live, you can begin to add the In-App Link to a push notification. When composing a new push notification in the Mobile App Studio, drag and drop the In-App link draggable into your message.
This means the browser can have no windows open, and you'll still receive the push message in your service worker, because the browser in running in the background. The only time a push won't be received is when the browser is completely closed, i.e. not running at all (no marking).
The good news is that Pusher Beams now has Safari support and we've been able to hide most of the complexity for developers by: We provide a unified API for triggering notifications to Push API browsers and Safari – you can send to both with a single API call (as well as to iOS/Android)
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
}
})
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)
);
})
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 endpointuser.push_subscription.key, user.push_subscription.auth_key
are again methods defined in the same modelInside /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)
);
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With