workbox-window implement unregister and cache clear functionality

Created on 14 Jun 2019  路  3Comments  路  Source: GoogleChrome/workbox

Welcome! Please use this template for reporting bugs or requesting features. For questions about using Workbox, the best place to ask is Stack Overflow, tagged with [workbox]: https://stackoverflow.com/questions/ask?tags=workbox

Library Affected:
workbox-window, 4.3.1

Browser & Platform:
Google Chrome

Issue or Feature Request Description:
I would like to have a simple functionality to unregister the service worker and clear all or specific caches or dbs in indexed DB and cache storage. This is common when you for example have an emergency when you distributed for example crappy code which can be only removed by clearing the cache or service worker. Other use case is the application or browser is used by multiple users and they are not allowed to see the data of another user. --> using that on logout or session expiration.

My code until now:

window.unregisterServiceWorker = async function () {
                var registrations = await navigator.serviceWorker.getRegistrations();
                if (registrations.length > 0) {
                    //delete indexed db
                    indexedDB.deleteDatabase("workbox-expiration");

                    //delete local cache
                    var cacheKeys = await caches.keys();
                    for (const key of cacheKeys) {
                        caches.delete(key);
                    }

                    //unregister all registrations of servive worker
                    for (const registration of registrations) {
                        await registration.unregister();
                    }

                    //reload page without service worker
                    window.location.reload(true);
                }
            }

When reporting bugs, please include relevant JavaScript Console logs and links to public URLs at which the issue could be reproduced.

Feature Request workbox-window

Most helpful comment

@alexander-theijs postMessage can help
Window

listenMessagesFromServiceWorker () {
  navigator.serviceWorker.onmessage = async (event) => {
     switch (event.data.action) {
        case 'RELOAD':
          window.location.reload()
          break
     }
  }
}

window.unregisterServiceWorker = async function () {
  // The cleaning part could be on service worker side
  indexedDB.deleteDatabase("workbox-expiration")
  const cacheKeys = await caches.keys()
  for (const key of cacheKeys) {
    caches.delete(key)
  }

  // unregister all registrations of servive worker
  const registrations = await navigator.serviceWorker.getRegistrations()
  for (const registration of registrations) {
    registration.postMessage({ action: 'UNREGISTER' })
  }
}

Service worker

self.addEventListener('message', async (event) => {
  switch (event.data.action) {
    case 'UNREGISTER':
      self.registration.unregister()

      const windows = await self.clients.matchAll({ type: 'window' })
      for (const window of windows) {
        window.postMessage({ action: 'RELOAD' })
      }
      break
  }
})

All 3 comments

Problem with my code is it doesn't refresh all tabs because we dont have the service worker global scope in client.

@alexander-theijs postMessage can help
Window

listenMessagesFromServiceWorker () {
  navigator.serviceWorker.onmessage = async (event) => {
     switch (event.data.action) {
        case 'RELOAD':
          window.location.reload()
          break
     }
  }
}

window.unregisterServiceWorker = async function () {
  // The cleaning part could be on service worker side
  indexedDB.deleteDatabase("workbox-expiration")
  const cacheKeys = await caches.keys()
  for (const key of cacheKeys) {
    caches.delete(key)
  }

  // unregister all registrations of servive worker
  const registrations = await navigator.serviceWorker.getRegistrations()
  for (const registration of registrations) {
    registration.postMessage({ action: 'UNREGISTER' })
  }
}

Service worker

self.addEventListener('message', async (event) => {
  switch (event.data.action) {
    case 'UNREGISTER':
      self.registration.unregister()

      const windows = await self.clients.matchAll({ type: 'window' })
      for (const window of windows) {
        window.postMessage({ action: 'RELOAD' })
      }
      break
  }
})

Going to test this one ASAP :3

Was this page helpful?
0 / 5 - 0 ratings