Push-уведомление Google Chrome

Я внедряю хромированные push-уведомления для пользователей моего сайта. Что я и умею делать успешно. У меня два вопроса?

1) как получить предыдущий идентификатор подписки, когда я блокирую уведомление в настройках браузера. Мне нужно удалить идентификатор подписки с моего внутреннего сервера.

2) всякий раз, когда я перезагружаю веб-сайт, метод pushManager.subscribe запускается каждый раз, когда я отправляю идентификатор подписки на сервер, из-за чего 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);
  });
}

сервис-воркер.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);
      }
    })
  );
});

person Mubashir    schedule 24.05.2016    source источник


Ответы (2)


Лучшие советы, которые я могу дать:

  1. Keep track of your subscription (especially what you send to your server) in indexDB. Why IndexDB?
    1. You can update indexDB in the window and in the serviceworker. This is important as you'll first get a PushSubscription in the window, but serviceworker will dispatch pushsubscriptionchange events which you should listen for and attempt to get a new PushSubscription, if you can.
  2. Когда страница загрузится, проверьте indexDB на наличие старой подписки, если она существует, сравните ее с getSubscription() (т.е. вашей текущей подпиской). Эта проверка должна включать любые значения, которые вам нужны на стороне сервера, например, когда браузеры переходят от не поддержки полезной нагрузки к их поддержке, они переходят от отсутствия ключей к внезапному появлению ключей — поэтому вам следует проверить, у вашего сервера есть эти ключи или нет.
  3. НЕ ИСПОЛЬЗУЙТЕ какие-либо API для GCM, они НЕ будут работать в других браузерах (Firefox, Opera, браузер Samsung + другие в будущем) и не нужны.
person Matt Gaunt    schedule 22.08.2016

1) Вы не можете получить предыдущий reg id. Есть способы:

  1. Каждый раз, когда вы подписываетесь на уведомления, вы можете сохранить их в локальной базе данных Chrome (например, indexdb), а когда вы подписываетесь в другой раз, вы просто восстанавливаете свой предыдущий идентификатор reg из этой базы данных.
  2. Когда вы отправляете уведомление в GCM, он отвечает вам каноническими идентификаторами и другой информацией о правильности регистрационных идентификаторов, поэтому вы можете удалить недействительный.

2) Вы должны сначала проверить, существует ли идентификатор подписки, а затем подписаться, если нет:

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);
  });
}
person Danil Gudz    schedule 30.05.2016