I would like to implement push notifications to a website, but I can’t trigger push event with PHP and web push library, even though it seems that message is sent successfully.
I’ve tried to trigger the event from the console(chrome), and It works.
Service worker:
self.addEventListener('install', async event => { // works fine console.log('install event') }); self.addEventListener("push", function(event) { // console logs work only when I press push button in the console console.log( 'push event' ); console.log( event ); var data = event.data.json(); event.waitUntil(self.registration.showNotification(data.title, { body: data.body, icon: data.icon, tag: data.tag })); });
Php endpoint(push.php):
<?php require_once __DIR__ . '/vendor/autoload.php'; use MinishlinkWebPushWebPush; use MinishlinkWebPushSubscription; $auth = [ 'VAPID' => [ 'subject' => 'mailto:me@website.com', // can be a mailto: or your website address 'publicKey' => 'BL9qxdhqL_CM1ROLo6AUfeBvEyUuD7EHT3lAz8ksBZSYPsdE6q__uU2FoX9lr5FtmWtlHs-HRMHen3Ki8WWSVA4', // (recommended) uncompressed public key P-256 encoded in Base64-URL 'privateKey' => '7ldG3QYcY9KStB07ytTnd0CRCVSxbHfHYLyWEmgBKo0', // (recommended) in fact the secret multiplier of the private key encoded in Base64-URL ], ]; $subscription = Subscription::create([ // I'm using post just for test, in production I will fetch endpoints from database 'endpoint' => $_POST['endpoint'], // I get the value from subscription object "keys" => [ 'p256dh' => 'BL9qxdhqL_CM1ROLo6AUfeBvEyUuD7EHT3lAz8ksBZSYPsdE6q__uU2FoX9lr5FtmWtlHs-HRMHen3Ki8WWSVA4', 'auth' => '7ldG3QYcY9KStB07ytTnd0CRCVSxbHfHYLyWEmgBKo0' ], 'contentEncoding' => 'aesgcm', ]); $webPush = new WebPush($auth); $sent = $webPush->sendNotification($subscription, 'Hi'); foreach ($webPush->flush() as $report) { $endpoint = $report->getRequest()->getUri()->__toString(); if ($report->isSuccess()) { // I get this in the response echo "[v] Message sent successfully for subscription {$endpoint}."; } else { echo "[x] Message failed to sent for subscription {$endpoint}: {$report->getReason()}"; } }
My javascript:
async function registerSw () { if ('serviceWorker' in navigator) { navigator.serviceWorker.register('./sw.js').then(function(registration) { subscribeToPush(); }).catch(error => console.log(error)); } else { alert('Service workers not supported'); } } async function subscribeToPush () { navigator.serviceWorker.ready.then(function(registration) { registration.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: urlB64ToUint8Array('BL9qxdhqL_CM1ROLo6AUfeBvEyUuD7EHT3lAz8ksBZSYPsdE6q__uU2FoX9lr5FtmWtlHs-HRMHen3Ki8WWSVA4') }) .then(function(subscription) { // The subscription was successful ajax(subscription); }) .catch(function(e) { console.log( e ); }); }); } function urlB64ToUint8Array(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 ajax (subscription) { console.log( 'in ajax' ); console.log( subscription ); $.ajax({ url: 'push.php', type: 'POST', data: { 'endpoint': subscription.endpoint, }, success: function( response ) { // response = JSON.parse( response ); console.log(typeof response); console.log(response); // I get message was sent successfuly here }, error: function (xhr, status, error) { console.log( xhr.responseText ); } }); }
Service worker is registered successfully, I can ask for user permission and send values from subscription object back to backend, everything goes fine with web push, but event is still not being triggered.
Any help would be appreciated, thanks.
Advertisement
Answer
Problem was that “keys” value of associative array that I’ve passed to Subscription::create had wrong hardcoded values.