Web 推送通知点击不起作用

Web push notifications click doesn't work

我正在尝试做可点击的网络推送通知,当用户点击它时,他应该被重定向到一些 url。

我正在使用 Laravel 5.4 软件包: https://github.com/laravel-notification-channels/webpush

下面是部分代码:

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>

服务-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);
        }
    })
);
});

通知:

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]);
}

通常它会显示通知,但当我试图点击它时我想被重定向到 https://google.com,但没有任何反应。您知道如何解决吗?

将 Google Chrome 设置重置为默认值后问题已解决。

找到解决方案。 动作方法接受标题和动作,但动作不是 url。您应该将 notificationclick 事件添加到您的 service-worker.js 文件中。

self.addEventListener('notificationclick', function (event) {
  event.notification.close();

  event.waitUntil(
    self.clients.openWindow('https://www.example.com/')
  );
});

参考 - https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerGlobalScope/notificationclick_event