代码之家  ›  专栏  ›  技术社区  ›  Cannon Moyer

获取pushmanager订阅时出错-javascript

  •  7
  • Cannon Moyer  · 技术社区  · 8 年前

    我有下面的代码来注册一个服务工作者并请求用户允许通知。当用户允许推送通知返回承诺后,我会收到一个错误。 serviceWorkerRegistration.pushManager.getSubscription() null . 当我关闭浏览器并再次强制此函数调用时,它不会出错。我不明白为什么。这是我的代码:

    window.vapidPublicKey = new Uint8Array([4, 45, ...]); 
    if (navigator.serviceWorker) {
      navigator.serviceWorker.register('/serviceworker.js')
      .then(function(reg) {
         console.log('Service worker change, registered the service worker');
      });
    }
    // Otherwise, no push notifications :(
    else {
      console.error('Service worker is not supported in this browser');
    }
    
    navigator.serviceWorker.ready.then((serviceWorkerRegistration) => {
      console.log("ready");
      serviceWorkerRegistration.pushManager
      .subscribe({
        userVisibleOnly: true,
        applicationServerKey: window.vapidPublicKey
      });
    });
    
    
    
    // application.js
    
    // Let's check if the browser supports notifications
    if (!("Notification" in window)) {
      console.error("This browser does not support notifications.");
    }
    
    // Let's check whether notification permissions have already been granted
    else if (Notification.permission === "granted") {
      console.log("Permission to receive notifications has been granted");
    }
    
    // Otherwise, we need to ask the user for permission
    else if (Notification.permission !== 'denied') {
      Notification.requestPermission(function (permission) {
        // If the user accepts, let's create a notification
        if (permission === "granted") {
          console.log("Permission to receive notifications has been granted");
          saveSubscriptionToDatabase();
        }
      });
    }
    
    function saveSubscriptionToDatabase(){
    
          navigator.serviceWorker.ready
          .then((serviceWorkerRegistration) => {
            console.log(serviceWorkerRegistration.pushManager.getSubscription());
            serviceWorkerRegistration.pushManager.getSubscription()
            .then((subscription) => {
              $.post("/users/save_subscription", { subscription: subscription.toJSON() });
            });
          });
    
    }
    

    错误:

    Uncaught (in promise) TypeError: Cannot read property 'toJSON' of null
    at serviceWorkerRegistration.pushManager.getSubscription.then
    

    更新:

    所以我添加了以下按钮:

     <input type="button" onclick="saveSubscriptionToDatabase();" value="test">
    

    只要我通过按钮click调用函数,所有的JS和Post请求就可以正常工作,但是当我从检查权限状态的条件调用函数时,它仍然像以前一样失败。

    更新2:

    我试过再次编写代码,但从另一个角度。

    function registerServiceWorker() {
      return navigator.serviceWorker.register('serviceworker.js')
      .then(function(registration) {
        console.log('Service worker successfully registered.');
        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.');
        }
      });
    }
    
    
    function subscribeUserToPush() {
      return navigator.serviceWorker.register('serviceworker.js')
      .then(function(registration) {
        const subscribeOptions = {
          userVisibleOnly: true,
          applicationServerKey: new Uint8Array("key goes here")
    
        };
    
        return registration.pushManager.subscribe(subscribeOptions);
      })
      .then(function(pushSubscription) {
        console.log("never called");
        console.log('Received PushSubscription: ', JSON.stringify(pushSubscription));
        return pushSubscription;
      });
    }
    
    registerServiceWorker();
    askPermission();
    subscribeUserToPush();
    

    命令链的最后一部分 subscribeUserToPush() 我在哪里 console.log("never called"); 从不执行并且没有错误。我用Chrome67测试这个。我肯定 registration.pushManager.subscribe(subscribeOptions); 被调用。

    1 回复  |  直到 8 年前
        1
  •  1
  •   Cannon Moyer    8 年前

    navigator.serviceWorker.register('serviceworker.js') /

    navigator.serviceWorker.register('/serviceworker.js')