Skip to content
Lahiru Jayakody edited this page Dec 2, 2016 · 5 revisions

Push notifications for your webapp!

Introduction

This repository contains and explains necessary steps to configure web push notifications for your webapp on Safari and Push API supported browsers as listed below:

  • Chrome 49+
  • Firefox 52+
  • Opera 42+
  • Safari 10+

This tutorial uses Java in Back-end and JavaScript in front-end. IntelliJ IDEA configured for Java, Maven and PHP is recommended to use for this tutorial. Source code can be downloaded from top of this site. The code is written for demonstration purpose and you have to learn and modify the code to use in your production environment. Follow the steps below to configure web push notifications.

What is a web push notification?

Push notification

Mobile push notifications can be sent from your back-end to some device owner's notification service such as Google's FCM or Apple's APNS. Whenever the receiver device has the internet connectivity, pending messages are fetched from device owner's notification service and displayed to the user. To do this, your message recipient should have installed a push notification enabled mobile application given by you. Web push notifications or browser push notifications are somewhat different. Those are delivered to a web browser. Message recipient should have allowed notifications for your webapp or website by visiting the url from a push notification supported browser. It's the time for sending push notifications to your webapp visitors.

Let's start

You can download the source code related to this tutorial from below or clicking the link at the top of this page. Feel free to contribute to the repository.

Source code: Browser-push

If you are not willing to send notifications for Safari users, you can skip almost all the steps 😄. Safari doesn't support Push API which is the W3C standard for web push notification protocol yet. But Chrome, Firefox and Opera latest versions has nicely done that. Therefore, we have to handle Safari separately while other all browsers can be considered as one. Let's say Safari and non-Safari.


1. Preparing client-side scripts

Open the project in IntelliJ IDEA.

Guide lines

  1. Browse front-end/keygen.html. Generate and note down the keys.

  2. Set const applicationServerPublicKey value
    in front-end/sw.js and front-end/main.js using generated server public key.

  3. Now your client-side scripts are ready to test on non-safari browsers.

  4. Open front-end/index.html in browser using any HTTP Server. You should be able to access to index.html from similar url as following.
    http://localhost:65124/browser-push/front-end/index.html
    DNS should be localhost. Otherwise, it should be https://
    Press Load script button then Enable Push Messaging. An input box will appear. Note down the JSON string from there as user subscription.

    This JSON object is called user subscription. In production environment, you should send this subscription to your backen-end and it should be persisted against some user identification. Later your back-end will use that user subscription objects to send push notifications to subscribed users. For demonstration purpose, you can copy it now and hard code in server code.

If you need to send notifications to Safari browser, following additional steps are needed.

  1. Create certificates (.p12 and .cer) and a website push id for your domain from Apple developer site. Refer Registering with Apple section in Configuring Safari Push Notifications article.

  2. Replace the var domain value in front-end/main.js with your website push id. It will look like web.com.example

    Then you need to setup a RESTful web service which will be called every time some Safari user is trying to subscribe for your webapp. Therefore, Safari push notification protocol needs 3 components to work together as following figure.

    Safari-handshake

    In above diagram, pink color box Returns push package needs to be done by our RESTful web service. Push package is a zip file which contains some files and it's hashes. Although Apple developer page instructs to build the Push package dynamically, in our implementation we will create it once and RESTful service will serve it as a static resource.

  3. Navigate to back-end/safari_push_package_creator/pushPackage.raw/.
    Modify the files as you needed. Please refer the Building the Push Package section in Configuring Safari Push Notifications article.

    If you are planing to add Safari push notification support to multiple domain names, specify those as "allowedDomains"
    in back-end/safari_push_package_creator/pushPackage.raw/website.json.
    Parameter "webServiceURL" specifies the path where the Safari RESTful service will be deployed at. authenticationToken will be not using to identify users in our implementation. So keep it as it is. Further, you can have your own iconset.

  4. Set $certificate_path, $certificate_password variables
    in back-end\safari_push_package_creator\index.php to match your .p12 certificate.

  5. Run that php file.

php index.php

6. Then a push package for your webapp will be created at following path    
back-end/safari_webservice_backend/binaries/push-package.zip`
7. Now make the `push-api.war` by packaging project `safari_webservice_backend`.
    ```shell
> mvn package
  1. Deploy the push-api.war file in Tomcat or other container. After the deployment, "webServiceURL" specified in website.json should matches the context path of deployed web application.
    If everything works fine,

    • http://webServiceURL/v1/ should response with BAD REQUEST
    • http://pushPackages/v1/web.com.example should download zip file push-package.bin.
  2. Now you can test Safari push notifications using front-end/index.html.

  3. A confirmation box should be displayed when Load script button is clicked. Otherwise, check developer console outputs. If output is printed with deviceToken=null, this is a problem of your safari RESTful service or created push package. See push-api.war logs for troubleshooting.

  4. If everything works fine, input box with device a should be appeared. Note down it as Safari subscription. It is needed when sending notifications.

    In production environment, you should send this subscription to your backen-end and it should be persisted against some user identification. Later your back-end will use that user subscription objects to send push notifications to subscribed users. For demonstration purpose, you can copy it now and hard code in server code.

References

If you encounter any problem with above guide lines, following resources from the original authors will be helpful.


2. Sending push notifications for subscribed users

Guide lines

  1. Navigate to universal_web_notification_sender project. Set previously generated (in Step 1.1) server keys in PushServerVars.java.

  2. Add your subscriptions in Sender.java as follows.

PushSubscription nonSuffariSubscription = new PushSubscription( "subscriptionJson" ) String suffariSubscription = "subscriptionToken";

3. Sample notification should be delivered to your browser when you run `Sender.java` class.

**If you need to send notifications to Safari browser, following additional steps are needed.**

1. Place your **.cer file** (i.e apn_developer_identity.cer), **.p12 file** (i.e. private_dev_key.p12) and **.certSigningRequest** (i.e CertificateSigningRequest.certSigningRequest) in same directory and execute following commands to create **apn_developer_identity.p12**.

    ```dos
openssl x509 -in apn_developer_identity.cer -inform DER -out apn_developer_identity.pem -outform PEM}
openssl pkcs12 -nocerts -out private_dev_key.pem -in private_dev_key.p12
openssl rsa -out private_key_noenc.pem -in private_dev_key.pem
openssl pkcs12 -export -in apn_developer_identity.pem -inkey private_key_noenc.pem -certfile CertificateSigningRequest.certSigningRequest -name "apn_developer_identity" -out apn_developer_identity.p12
  1. Place your apn_developer_identity.p12 in universal_web_notification_sender project root.
  2. Change your certificate passkey in private static void sendToSafari() method in Sender.java class.
  3. Uncomment sendToSafari(safariSubscription, safariPayload); line
    in public static void main(String[] args) method in Sender.java class.
  4. Sample notification should be delivered to your Safari when you run Sender.java class.

References

If you encounter any problem with above guide lines, following resources from the original authors will be helpful.

Browser Push Github page

Clone this wiki locally