Skip to content
Advertisement

PHP successful webpush not triggering push event listener in SW

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.

User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement