When working on products or services it’s often necessary to create separate applications for desktop and mobile devices (Android, iOS, WindowsPhone). This implies you’ll need to hire a Java, Objective-C, C# and web developers, so project costs are increased significantly. This problem could be reduced with Progressive Web Apps.
What Progressive Web Apps (PWA) are is explained here. In this article, I will demonstrate an example application that uses some PWA features (caching, push notifications). We won’t talk about the specifics of the implementation (you can see the code). I want to show off some PWA functions and problems that came up during implementation and deployment that are not explicitly documented.
Progressive Pizza overview
The application is a mock-up of a pizza ordering service. It will have two parts: backend and frontend. We will use a PWA app shell for frontend and we will display some push notifications from the backend. The backend will store active app users data (email and service worker subscribtion data). The code for the backend is available here, and for frontend here.
To use push notifications, Google Firebase Account and Firebase authorization key are needed. An account can be created here.
The workings of push notifications are explained here, but there are some understatements in the official guide that we will clarify in this article.
Roll your own webserver with notifications logic
In Firebase Console there is no way to send messages to a web application. Firebase Console only allows to send notifications to Android and iOS apps. That means we have to implement our own server with a client registration mechanism and logic.
When a web application service worker in the browser starts up, it registers itself to our server with push notifications subscribtion data (id, keys etc.). There is no way to get all subscribed clients from Firebase API, so we have to keep and maintain active users and their subscribtions on our own. Firebase messaging is only a protocol for transporting messages from the server to all clients.
Sending notifications without any data doesn’t require encryption. If we want to send some data FCM forces us to encrypt it – otherwise push notifications will be delivered but without any payload.
To do this we suggest the web-push NodeJS module. Under the hood it uses some elliptic curve cryptography and the Diffie-Hellman system.
Why does the payload have to be encrypted?
Because FCM is the middleman here. FCM should not be able to read any sensitive data. FCM is only one nofitication service. If the client uses, for example, Mozilla Firefox, they have their own notifications service.
The server should run over https. Service workers security assumptions require this. If it’s not running on https, you will get a message like this:
When the app start it will ask the user for permission for displaying notifications.
Just like in the desktop version, the user has to allow for displaying notifications.