Google Chrome推送通知

时间:2016-05-24 10:24:26

标签: javascript push-notification google-cloud-messaging web-push chrome-gcm

我正在为我的网站用户实施Chrome推送通知。我能成功做到这一点。 我有两个问题?

1)每当我阻止来自浏览器设置的通知时,如何获取先前的订阅ID。我必须从我的后端服务器中删除订阅ID

2)每当我重新加载网站时,每次我向服务器发送订阅ID时都会运行pushManager.subscribe方法,因为每次使用相同的订阅ID时,API都会发送

push.js

'use strict';

if ('serviceWorker' in navigator) {
  console.log('Service Worker is supported');
  navigator.serviceWorker.register('service_worker.js').then(function() {
    return navigator.serviceWorker.ready;
  }).then(function(reg) {
    console.log('Service Worker is ready :^)', reg);
    reg.pushManager.subscribe({userVisibleOnly: true}).then(function(sub) {
      console.log('endpoint:',JSON.stringify(sub.endpoint));
       console.log(sub.endpoint.substring('https://android.googleapis.com/gcm/send/'.length));
    });
  }).catch(function(error) {
    console.log('Service Worker error :^(', error);
  });
}

服务worker.js

'use strict';
var myurl;
console.log('Started', self);

self.addEventListener('install', function(event) {
  self.skipWaiting();
  console.log('Installed', event);
});

self.addEventListener('activate', function(event) {
  console.log('Activated', event);
});


self.addEventListener('push', function(event) {
  console.log('Push message', event);

      event.waitUntil(  
      fetch('/notify.json').then(function(response) { 
            return response.json().then(function(data) { 
            console.log(JSON.stringify(data));
                var title = data.title;  
                var body = data.body;  
                myurl=data.myurl;     

                return self.registration.showNotification(title, {  
                  body: body,  
                  icon: 'profile.png',  
                  tag: 'notificationTag'  
                }); 

            });  
      }).catch(function(err) {  
          console.error('Unable to retrieve data', err);

          var title = 'An error occurred';
          var body = 'We were unable to get the information for this push message';  

          return self.registration.showNotification(title, {  
              body: body,  
              icon: 'profile.png',  
              tag: 'notificationTag'  
            });  
        })  
      );   
});

  // var title = 'Vcona';
  // event.waitUntil(
  //   self.registration.showNotification(title, {
  //     'body': 'School Management',
  //     'icon': 'profile.png'
  //   }));



self.addEventListener('notificationclick', function(event) {
  console.log('Notification click: tag', event.notification.tag);
  // Android doesn't close the notification when you click it
  // See http://crbug.com/463146
  event.notification.close();
  var url = 'https://demo.innotical.com';
  // Check if there's already a tab open with this URL.
  // If yes: focus on the tab.
  // If no: open a tab with the URL.
  event.waitUntil(
    clients.matchAll({
      type: 'window'
    })
    .then(function(windowClients) {
      console.log('WindowClients', windowClients);
      for (var i = 0; i < windowClients.length; i++) {
        var client = windowClients[i];
        console.log('WindowClient', client);
        if (client.url === url && 'focus' in client) {
          return client.focus();
        }
      }
      if (clients.openWindow) {
        return clients.openWindow(myurl);
      }
    })
  );
});

2 个答案:

答案 0 :(得分:1)

我能给出的最佳建议:

  1. 在indexDB中跟踪您的订阅(尤其是您发送到服务器的订阅)。为什么选择IndexDB?
    1. 您可以在窗口和serviceworker中更新indexDB。这很重要,因为您首先会在窗口中获得PushSubscription,但是如果可以的话,服务工作人员将发送您应该监听的pushsubscriptionchange个事件,并尝试获取新的PushSubscription
  2. 当页面加载时,检查indexDB是否存在旧订阅(如果存在),将其与getSubscription()(即您当前的订阅)进行比较。此检查应包括您需要服务器端的任何值,例如,当浏览器从支持有效负载,到支持它们,从没有密钥,到突然有密钥 - 所以你应该检查是否你的服务器是否有这些密钥。
  3. 不要使用用于GCM的任何API,这将不适用于其他浏览器(Firefox,Opera,Samsung Browser +未来的其他浏览器),并且不需要。

答案 1 :(得分:0)

1)您无法获得之前的注册码。有办法:

  1. 每次订阅通知时,您都可以将其保存到本地chrome db(例如indexdb),当您再次订阅时,只需从此db恢复之前的reg。
  2. 当您向GCM发送通知时,它会向您回复规范ID以及有关注册表正确性的其他信息,以便您删除无效的
  3. 2)您必须先检查订阅ID是否已存在,然后订阅,否则:

    if ('serviceWorker' in navigator) {
      console.log('Service Worker is supported');
      navigator.serviceWorker.register('service_worker.js').then(function() {
        return navigator.serviceWorker.ready;
      }).then(function(reg) {
        console.log('Service Worker is ready :^)', reg);
        reg.pushManager.getSubscription().then(function(subscription) {
            if(!subscription) {
                reg.pushManager.subscribe({userVisibleOnly: true}).then(function(sub) {
                    console.log('endpoint:',JSON.stringify(sub.endpoint));
                    console.log(sub.endpoint.substring('https://android.googleapis.com/gcm/send    /'.length));
                    //send new subscription id to server
                    return;
                });
            }
        });
    
      }).catch(function(error) {
        console.log('Service Worker error :^(', error);
      });
    }