简体   繁体   中英

Service worker update event trigger

Following this link https://github.com/deanhume/pwa-update-available , I am trying to implement the service worker update, but I am facing issues like the event update is not getting triggered, which I think is related to my app design, which basically a SPA, means I am always on index.html,which behaves like app-shell and I am pushing the contents in the contents area, depending upon which button is clicked.

only other page is login/index.html

the contents for app.js to install/update service worker is like this:

let newWorker;
          function showUpdateBar() {
            let snackbar = document.getElementById('snackbar');
            snackbar.className = 'show';
          }
          // The click event on the pop up notification
          document.getElementById('reload').addEventListener('click', function(){
            newWorker.postMessage({ action: 'skipWaiting' });
          });
          if ('serviceWorker' in navigator) {
            navigator.serviceWorker.register('/pwa/sw.js').then(reg => {
              console.log( 'ServiceWorker registration successful with scope: ', registration.scope );
              reg.addEventListener('updatefound', () => {
                // A wild service worker has appeared in reg.installing!
                newWorker = reg.installing;
                newWorker.addEventListener('statechange', () => {
                  // Has network.state changed?
                  switch (newWorker.state) {
                    case 'installed':
                      if (navigator.serviceWorker.controller) {
                        // new update available
                        showUpdateBar();
                      }
                      // No update available
                      break;
                  }
                });
              });
            });
            let refreshing;
            navigator.serviceWorker.addEventListener('controllerchange', function () {
              if (refreshing) return;
              window.location.reload();
              refreshing = true;
            });
          }  

and sw.js file contents are like this:

var cacheName = 'v28';

self.addEventListener('install', event => {
  event.waitUntil(
    caches.open(cacheName)
      .then(cache => cache.addAll([
        "/pwa/index.html",
        "/pwa/main.css",
        "/pwa/js/app/app.js",
        "/pwa/js/app/libs/api.js",
        '/pwa/query.js',
        '/pwa/js/libs/localforage.min.js',
        '/pwa/js/libs/utils.js'
      ]))
  );
});



self.addEventListener('message', function (event) {
  if (event.data.action === 'skipWaiting') {
    self.skipWaiting();
  }
});

// Allow sw to control of current page
self.addEventListener('activate', event => {
  console.log('Activating new service worker...');

  const cacheWhitelist = [cacheName];

  event.waitUntil(
    caches.keys().then(cacheNames => {
      return Promise.all(
        cacheNames.map(cacheName => {
          if (cacheWhitelist.indexOf(cacheName) === -1) {
            return caches.delete(cacheName);
          }
        })
      );
    })
  );
});

self.addEventListener('fetch', function (event) {
  event.respondWith(
    caches.match(event.request)
      .then(function (response) {
        if (response) {
          return response;
        }
        return fetch(event.request);
      })
  );
});

the partial-contents of index.html:

<div id="snackbar">A new version of this app is available. Click <a id="reload">here</a> to update.</div>

so basically the issue I am facing is, triggering the update, when I am changing the version number like v28 to v29 and reload the page, I am getting the prompt, but I am not getting the prompt even when I logout, login or exit and reopen the app.

How I can fix this?

Note:PWA is my progressive app folder, I am using php/yii2 as backend and not using node server or other JS framework.

the service worker registration routine you have only triggers when you index.html is loaded in the browser. It is the only time that code is executed.

Unless you periodically poll your server or possibly open a websocket (sort of expensive just for this) you wont know if a new service worker is available. You could have the user register for push notifications....too much headache for this.

So pool the server every few hours or days for an update.

If there is an update you can trigger an update routine.

I would put the polling logic in the actual service worker code to keep it off the UI, if you are a SPA you are already locking the UI thread enough LOL.

There are lots of ways to skin this cat, setTimeout(..., {lots of seconds}), when the service worker wakes from being dormant, etc.

If you can make a HEAD request that would keep the network traffic to a minimum.

If there is an update you could then post a message to the UI to update the service worker.

This is not what I would call trivial code. I do similar stuff to keep my cached assets up to date, so I have been there:)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM