代码之家  ›  专栏  ›  技术社区  ›  SakuragiRokurota

Web推送通知单击无效

  •  1
  • SakuragiRokurota  · 技术社区  · 6 年前

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

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

    以下是一些代码:

    应用程序。刀身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>
    

    服务人员。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 ,但什么也没发生。你知道怎么修吗?

    2 回复  |  直到 6 年前
        1
  •  0
  •   SakuragiRokurota    6 年前

    在将Google Chrome设置重置为默认设置后,该问题已得到解决。

        2
  •  0
  •   Jakub Adamec Hamidreza    2 年前

    找到了解决方案。 action方法接受title和action, 但操作不是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