Search code examples
javascriptlaravel-5push-notificationweb-push

Web push notifications click doesn't work


I'm trying to do web push notifications that are clickable and when user click on it he should be redirected to some url.

I'm using Laravel 5.4 with package: https://github.com/laravel-notification-channels/webpush

Here is some of the code:

app.blade.php

 <script>
  var _registration = null;
  function registerServiceWorker() {
    return navigator.serviceWorker.register('{{ asset('assets/js/service-worker.js') }}')
        .then(function(registration) {
          console.log('Service worker successfully registered.');
          _registration = registration;
          return registration;
        })
        .catch(function(err) {
          console.error('Unable to register service worker.', err);
        });
  }
  function askPermission() {
    return new Promise(function(resolve, reject) {
      const permissionResult = Notification.requestPermission(function(result) {
        resolve(result);
      });
      if (permissionResult) {
        permissionResult.then(resolve, reject);
      }
    })
        .then(function(permissionResult) {
          if (permissionResult !== 'granted') {
            throw new Error('We weren\'t granted permission.');
          }
          else{
            subscribeUserToPush();
          }
        });
  }
  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 getSWRegistration(){
    var promise = new Promise(function(resolve, reject) {
      // do a thing, possibly async, then…
      if (_registration != null) {
        resolve(_registration);
      }
      else {
        reject(Error("It broke"));
      }
    });
    return promise;
  }
  function subscribeUserToPush() {
    getSWRegistration()
        .then(function(registration) {
          console.log(registration);
          const subscribeOptions = {
            userVisibleOnly: true,
            applicationServerKey: urlBase64ToUint8Array(
                "{{env('VAPID_PUBLIC_KEY')}}"
            )
          };
          return registration.pushManager.subscribe(subscribeOptions);
        })
        .then(function(pushSubscription) {
          console.log('Received PushSubscription: ', JSON.stringify(pushSubscription));
          sendSubscriptionToBackEnd(pushSubscription);
          return pushSubscription;
        });
  }
  function sendSubscriptionToBackEnd(subscription) {
    return fetch('/api/save-subscription/{{Auth::user()->id}}', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(subscription)
    })
        .then(function(response) {
          if (!response.ok) {
            throw new Error('Bad status code from server.');
          }
          return response.json();
        })
        .then(function(responseData) {
          if (!(responseData.data && responseData.data.success)) {
            throw new Error('Bad response from server.');
          }
        });
  }
  function enableNotifications(){
    //register service worker
    //check permission for notification/ask
    askPermission();
  }
  registerServiceWorker();
</script>

service-worker.js

    self.addEventListener('push', function(event) {
    if (event.data) {
        var data = event.data.json();

        self.registration.showNotification(data.title, {
            body: data.body,
            icon: data.icon
        });

        console.log('This push event has data: ', event.data.text());
    } else {
        console.log('This push event has no data.');
    }
   });

self.addEventListener('notificationclick', function(event) {
  console.log('Notification click: tag ', event.notification.tag);
  event.notification.close();
  var url = 'https://google.com';
  console.log('kliknieto');
  event.waitUntil(
    clients.matchAll({
        type: 'window'
    })
    .then(function(windowClients) {
        for (var i = 0; i < windowClients.length; i++) {
            var client = windowClients[i];
            if (client.url === url && 'focus' in client) {
                return client.focus();
            }
        }
        if (clients.openWindow) {
            return clients.openWindow(url);
        }
    })
);
});

Notification:

public function toWebPush($notifiable, $notification)
{
    return (new WebPushMessage)
        ->title('Some title')
        ->icon(asset("img/img.jpg"))
        ->body('Some body')
        ->action('View action', 'view_action')
        ->data(['id' => $notification->id, 'link' => $this->link]);
}

Generally it display the notification, but when I am trying to click on it I want to be redirected to https://google.com, but nothing happens. Do you have any idea how to fix it?


Solution

  • The problem has been solved after reset Google Chrome settings to default.