Push Notifications

Part 2 - Obtaining User Permissions and Managing Subscriptions for Web Push Notifications

Sanjeev Kumar
March 4, 2024
Explore push notification service workers essential steps for implementing web push notifications, from requesting user permission to managing subscription objects. Includes best practices & debugging tips.
TABLE OF CONTENTS

Implementing web push notifications entails numerous critical steps, including requesting user permission and managing subscription objects. This article explores these aspects in depth, offering guidance, examples, and best practices for developers seeking to effectively integrate push notifications in their projects. Specifically, we discuss:

  1. Requesting user permission using the Notification API's requestPermission() method
  2. Distinguishing permission states ('granted', 'default', 'denied')
  3. Introducing pushManager.subscribe(), encoding public keys, and associating them with users
  4. Secure storage and management of subscription objects
  5. Debugging tips for Push Notification Service Workers

Read all parts of this push notification service workers series here:

  1. Part 1 - Getting Started with Web Push Notifications Service Workers
  2. Part 2 - Obtaining User Permissions and Managing Subscriptions for Web Push Notifications
  3. Part 3: Crafting Dynamic and Feature-Rich Push Notifications

Extensity: A Popular Extension Manager

Many users leverage extension managers like Extensity to organize and enable/disable browser extensions conveniently. Due to this behavior, it's imperative to acknowledge such usage patterns and accommodate variations in extension availability, as it impacts user interaction with push notifications.

Requesting User Permission

Seeking user approval is essential prior to sending web push notifications. Invoke the Notification.requestPermission() method to trigger the permission dialog.

        
            async function requestUserPermission() {
              const permissionStatus = await Notification.requestPermission();
              console.log('Permission Status:', permissionStatus);
            }
        
    

Returned values indicate the permission state, falling into one of three categories:

  • 'granted': The user explicitly authorized push notifications.
  • 'default': The user did not grant or deny push notifications. This typically occurs when the permission was initially approved but later withdrawn.
  • 'denied': The user rejected the permission request or disabled push notifications entirely.

Handling permission states intelligibly improves the user experience, catering to diverse requirements and contextual situations.

Creating and Encoding Public Keys

Leverage libraries like [web-push] to produce cryptographic materials, such as public and private keypairs.

        
            import * as eccrypto from 'eccrypto';

            /** Generate asymmetric keys */
            async function generateKeypair() {
              const privateKeyBuffer = await eccrypto.generatePrivate();
              const publicKeyBuffer = eccrypto.getPublic(privateKeyBuffer);
              const privateKeyHex = Buffer.from(privateKeyBuffer).toString('hex');
              const publicKeyHex = Buffer.from(publicKeyBuffer).toString('hex');

              return {
                privateKey: privateKeyHex,
                publicKey: publicKeyHex,
              };
            }

            /** Encode public key */
            function urlBase64ToUint8Array(base64String) {
              const padding = '='.repeat((4 - (base64String.length % 4)) % 4);
              const base64 = (base64String + padding).replace(/\-/g, '+').replace(/\_/g, '/');
              const rawData = atob(base64);
              const outputArray = new Uint8Array(rawData.length);

              for (let i = 0; i < rawData.length; ++i) {
                outputArray[i] = rawData.charCodeAt(i);
              }
              return outputArray;
            }
            
        
    

Subscribing to Push Services and Encoding Public Keys

Prepare encryption keys and pass them as an option object alongside the service worker registration.

        
            async function subscribeToPushService(registration) {
              const keys = await generateKeypair();
              const convertedVapidKey = urlBase64ToUint8Array(keys.publicKey);
              const options = {
                userVisibleOnly: true,
                applicationServerKey: convertedVapidKey,
              };
              const subscription = await registration.pushManager.subscribe(options);
              console.log('Push Subscription Object:', subscription);
            }
        
    

Retrieving Active Subscriptions

Fetch existing subscriptions using pushManager.getSubscription().

        
            async function retrieveActiveSubscription(registration) {
              const activeSubscription = await registration.pushManager.getSubscription();
              console.log('Active Subscription:', activeSubscription);
            }
        
    

Secure Storage and Management of Subscriptions

Properly store subscription objects on the server, preferably using secure transport layer protocols such as HTTPS. Associate subscription records with user identities, permitting deletion upon user logout or explicit withdrawal of consent. Regularly validate subscription objects on the client, pruning invalid entries and refreshing stale records on the server.

Debugging Tips for Push Notification Service Workers

Service workers present intricate debugging difficulties. Apply these guidelines for a superior development experience:

  • Utilize dedicated tools designed for inspecting and tweaking service workers, such as the [Chromium DevTools Application Panel].
  • Guarantee dependable connectivity and prevent interference from proxies or firewalls, possibly disrupting service worker operation.
  • Mindful attention to service worker life cycle hooks and timely reactions to internal events proves essential.

Summary

Acquiring user permissions and skillfully handling subscription objects remain indispensable aspects of robust web push notifications. Gained proficiency in contemporary browser standards, adeptness in navigating permission states, judicious employment of encryption keys, diligent subscription management, and astute utilization of debugging instruments elevate the overall quality of user experiences and promote efficient development cycles.

Read all parts of this push notification service workers series here:

  1. Part 1 - Getting Started with Web Push Notifications Service Workers
  2. Part 2 - Obtaining User Permissions and Managing Subscriptions for Web Push Notifications
  3. Part 3: Crafting Dynamic and Feature-Rich Push Notifications
Written by:
Sanjeev Kumar
Engineering, SuprSend
ABOUT THE AUTHOR

What’s a Rich Text element?

The rich text element allows you to create and format headings, paragraphs, blockquotes, images, and video all in one place instead of having to add and format them individually. Just double-click and easily create content.

Static and dynamic content editing

A rich text element can be used with static or dynamic content. For static content, just drop it into any page and begin editing. For dynamic content, add a rich text field to any collection and then connect a rich text element to that field in the settings panel. Voila!

How to customize formatting for each rich text

Headings, paragraphs, blockquotes, figures, images, and figure captions can all be styled after a class is added to the rich text element using the "When inside of" nested selector system.

Implement a powerful stack for your notifications
By clicking “Accept All Cookies”, you agree to the storing of cookies on your device to enhance site navigation, analyze site usage, and assist in our marketing efforts. View our Privacy Policy for more information.