Web push notifications (WPN)
Web push notifications are clickable rich content messages that allow users to opt-in to timely updates from websites. The application supports listening to push notifications APIs and broadcasting the notifications, which can be consumed by different features within the application.
Enabling WPN
Note: For all web push notifications related features, the Angular service worker module is
leveraged.
Service worker
As service worker is required for the push notification to work, application-provided a default
service worker is registered which listens to push and notification click events and broadcasts
these events which different features can listen to.
- Push event : The service worker listens to the Push event, shows the notification and broadcasts a message with push data which different features can listen to.
- Notification click event : The service worker listens to the Notification click event, closes the notification and broadcasts a message with the notification data (including action details), which different features can listen to.
Subscribing and unsubscribing to notifications
- Subscribing to notifications: Is a complete implementation effort and by default, the
application provides a hook to subscribe during the login process. Just after login, the application
makes a call to subscribe the method defined inside
src/app/core/services/PushNotificationAbstractService (as of today it is just a
dummy method).
PushNotificationAbstractServiceshould be overridden to implement the subscribe method so that users can subscribe to notifications and this subscription can be persisted somewhere at the customer's end. The same customized service can be invoked from anywhere in the application to change the default behavior, which is subscription during login. - Unsubscribing to notifications: Again the dummy unsubscribe method from
src/app/core/services/PushNotificationAbstractService is called during logout
for the application-provided flow and it should be overridden to meet customer’s needs. At very
basic, this is how an overridden service will look like (the overridden service needs to be defined
inside store-extensions-src/app/core/services/Note: This is a very basic implementation and not desirable for production application.
import { Injectable, Injector } from '@angular/core';
import { PushNotificationAbstractService } from '@simcore/
services/push-notification-abstract.service';
import { SwPush } from '@angular/service-worker';
import { HttpClient, HttpResponse } from '@angular/common/http';
import { map, take } from 'rxjs/operators';
import { UIUtilsService } from '@sim-core/services/uiutils.
service';
@Injectable({
providedIn: 'root'
})
export class PushNotificationService extends
PushNotificationAbstractService {
readonly VAPID_PUBLIC_KEY = '<vapid key>';
isWPNSubscribed = false;
subsObj = null;
constructor(
protected injector: Injector,
public swPush: SwPush,
private http: HttpClient
) {
super(injector);
if (this.swPush.isEnabled) {
this.swPush.subscription
.pipe(take(1))
.subscribe(pushSubscription => {
if (pushSubscription) {
this.isWPNSubscribed = true;
}
});
}
}
public subscribe({}) {
this.subscribeToNotifications(null);
}
subscribeToNotifications(event) {
if (event) {
event.preventDefault();
}
this.swPush.requestSubscription({
serverPublicKey: this.VAPID_PUBLIC_KEY
})
.then(pushSubscription => {
this.http.post('https://<host-port>/<susbcribe-end-point>',
{'subscription': pushSubscription.toJSON(), 'any-other-data':''});
this.isWPNSubscribed = true;
})
.catch(err => console.error('Could not subscribe to
notifications', err));
}
public unsubscribe({}) {
this.unsubscribeToNotifications(null);
}
unsubscribeToNotifications(event) {
event.preventDefault();
this.swPush.subscription
.pipe(take(1))
.subscribe(pushSubscription => {
pushSubscription.unsubscribe().then(result => {
if (result) {
this.isWPNSubscribed = false;
this.http.post('https://<host-port>/<unsusbcribe-endpoint>',
{'data': 'data'})
} else {
console.log('Could not unsubscribe to notifications');
}
})
.catch(err => console.error('unsubcribe subscription failed',
err));
});
}
}
Invoking Push service
Invoking push service is a complete custom implementation and must be taken care by the customer. Typically, events when raised in Sterling Store Engagement or IBM® Sterling Order Management System must be captured, and the push service must be invoked with the correct data for it to be shown to the associated user.
A typical notification payload would look as follows:
{
"notification": {
"title": "Notification Title", //mandatory
"body": "Notification Message!",
"data": {
"dateOfArrival": Date.now(),
"primaryKey": 1
}
}
}Handling push and notification click events
As mentioned in service worker section, the application-provided service worker already takes
care of showing and closing the notification. Additionally, it broadcasts the push and notification
click events which the application can listen to for further processing. The application-provided
angular service worker module provides a way to subscribe to these events which can be used as follows:
this.swPush.messages.subscribe(message => {
console.log('Push message: ', message);
});
this.swPush.notificationClicks.subscribe(notificationMsg => {
console.log('Notification Click: ', notificationMsg);
});
Note: The
This code can be kept inside swPush is a reference to @angular/service-worker
modulePushNotificationService
service.Limitations
- Only supported on Chrome for Desktop and Android.
httpsonly support and works with only valid SSL certificates.- When a user logs in to the application for the first time after the May3rd upgrade, the user must reload the UI to make use of the service worker and hence push notifications.