yenren
yenren

Reputation: 501

Web-Push notification script working on Firefox but not on Chrome

I am building a web push notification system and I am using the concept used in this example:

https://github.com/Minishlink/web-push-php-example

I have the following code in my JS file. It checks for API support, checks if notifications are not disabled, registers the service worker, asks for permission to display notifications, if allowed subscribes the user and sends the details to the server. If the user is already subscribed, it updates the endpoint value in the DB.

When I run this on Firefox 61, it works fine, but when I run it on Chrome 67 I get this error:

Uncaught (in promise) TypeError: Cannot read property 'getKey' of null
    at pushSubscribe (notification.js:48)
    at navigator.serviceWorker.ready.then.then.subscription (notification.js:30)

My understanding is that Chrome does not detect the subscription when the service worker is registered and the user is subscribed, hence it gives the error. Any ideas how to fix this?

Thanks.

document.addEventListener('DOMContentLoaded', () => {
    // Feature detection
    if (!('serviceWorker' in navigator)) {
        alert('Service Worker API isn’t supported.');
    } else if (!('PushManager' in window)) {
        alert('Push API isn’t supported.');
    } else if (!('Notification' in window)) {
        alert('Notifications API isn’t supported.');
    } else if (!('showNotification' in ServiceWorkerRegistration.prototype)) {
        alert('Notifications aren’t supported.');

    // Check permission
    } else if (Notification.permission == 'denied') {
        alert('Notifications are disabled.');
    } else {

        // Register service worker
        navigator.serviceWorker.register('/service-worker.js').then(() => {
            navigator.serviceWorker.ready.then(serviceWorkerRegistration => serviceWorkerRegistration.pushManager.getSubscription()).then(subscription => {
                if (!subscription) {
                    // Subscribe user
                    navigator.serviceWorker.ready.then(serviceWorkerRegistration => serviceWorkerRegistration.pushManager.subscribe({
                        userVisibleOnly: true,
                        applicationServerKey: urlBase64ToUint8Array('BNwjaNBKGM13IAef-gJr7C95W3yLJe2F5X0zLnwacN3zCnZK15Vqf3ijeHl9k7K0yBFX3ZwxAmldPoVDpi6iETA'),
                    })).then(subscription => {
                        return pushSubscribe(subscription);
                    });
                }
                // Update endpoint
                return pushSubscribe(subscription);
            });
        });

        function urlBase64ToUint8Array(base64String) {
            const padding = '='.repeat((4 - base64String.length % 4) % 4);
            const base64 = (base64String + padding).replace(/\-/g, '+').replace(/_/g, '/');

            const rawData = window.atob(base64);
            const outputArray = new Uint8Array(rawData.length);

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

        function pushSubscribe(subscription) {
            const key = subscription.getKey('p256dh');
            const token = subscription.getKey('auth');
            const contentEncoding = (PushManager.supportedContentEncodings || ['aesgcm'])[0];

            return fetch('/scripts/notification-subscribe.php', {
                method: 'POST',
                body: JSON.stringify({
                    endpoint: subscription.endpoint,
                    publicKey: key ? btoa(String.fromCharCode.apply(null, new Uint8Array(key))) : null,
                    authToken: token ? btoa(String.fromCharCode.apply(null, new Uint8Array(token))) : null,
                    contentEncoding,
                    user: userId, // generated beforehand
                }),
            }).then(() => subscription);
        }
    }
});

Upvotes: 4

Views: 2422

Answers (1)

Siddharth Jain
Siddharth Jain

Reputation: 336

        if(subscription){
const key = subscription.getKey('p256dh');
            const token = subscription.getKey('auth');
            const contentEncoding = (PushManager.supportedContentEncodings || ['aesgcm'])[0];

            return fetch('/scripts/notification-subscribe.php', {
                method: 'POST',
                body: JSON.stringify({
                    endpoint: subscription.endpoint,
                    publicKey: key ? btoa(String.fromCharCode.apply(null, new Uint8Array(key))) : null,
                    authToken: token ? btoa(String.fromCharCode.apply(null, new Uint8Array(token))) : null,
                    contentEncoding,
                    user: 1,
                }),
            }).then(() => subscription);
        }
}

Just modify this function hope pushSubscription with if block it works

Upvotes: 2

Related Questions