edwardinchains
edwardinchains

Reputation: 119

Workbox 5.1.2 backgroundSync Queue configuration

I have recently migrated from Workbox 3.5.0 to Workbox 5.1.2

I am using Workbox SW via CDN

importScripts('https://storage.googleapis.com/workbox-cdn/releases/5.1.2/workbox-sw.js');

I have updated my service worker file to use the latest Plugin Classes and have renamed the classes appropriately - everything is working great!

The only real issue / confusion I am having is with the backgroundSync module. I have read through the documentation and have searched on Stackoverflow & Google for a solution / suggestion, but can't find anything that explicitly answers my question.

I am trying to add failed requests to a Queue that get retried once the network is restored.

workbox.routing.registerRoute(new RegExp('/\/php\/postPO.php/'),
  new workbox.strategies.NetworkOnly({
    plugins: [
      new workbox.backgroundSync.BackgroundSyncPlugin('po-data-queue', {
      maxRetentionTime: 24 * 60 * 2 
      })
    ]
  }),
 'POST'
);


const queue = new workbox.backgroundSync.Queue('po-data-queue-2');
self.addEventListener('fetch', (event) => {
  const promiseChain = fetch(event.request.clone()).catch((err) => {
    return queue.pushRequest({ request: event.request });
  });
event.waitUntil(promiseChain);
});

I know the above code doesn't work because if I give the 2 Queue names the same name then an error is thrown about using unique Queue names. Do I need both functions to use the backgroundSync module or is it one or the other. Also, do I need to create the indexedDB myself or does workbox handle this? When using workbox 3.5.0 I created the indexedDB and added failed requests like so (which worked fine):

function createIndexedDB() {
  if (!('indexedDB' in window)) {return null;}
  return idb.open('pos-data-queue', 1, function(upgradeDb) {
    if (!upgradeDb.objectStoreNames.contains('events')) {
      const eventsOS = upgradeDb.createObjectStore('events', {keyPath: 'key', autoIncrement: true});
    }
  });
}

const dbPromise = createIndexedDB();
function saveEventDataLocally(events) {
  console.log(events);
  if (!('indexedDB' in window)) {return null;}
  return dbPromise.then(db => {
    const tx = db.transaction('events', 'readwrite');
    const store = tx.objectStore('events');
    return Promise.all(events.map(event => store.put(event)))
   .catch((err) => {
    console.log(err);
    tx.abort();
    throw Error('Events were not added to the store');
   });
 });
}

const bgSyncPlugin = new workbox.backgroundSync.Plugin('pos-data-queue');
const networkWithBackgroundSync = new workbox.strategies.NetworkOnly({
  plugins: [bgSyncPlugin],
});

workbox.routing.registerRoute(
  /\/php\/postPO.php/,
  networkWithBackgroundSync,
 'POST'
);

I can't wrap my head around how this works, any help would be greatly appreciated

Upvotes: 0

Views: 1451

Answers (1)

mishamosher
mishamosher

Reputation: 1023

You are not required to use both BackgroundSyncPlugin and Queue. A unique name is required for each instance. The IndexedDB entries are managed by Workbox itself.

In your code examples I see a suspicious space (making the regex invalid) when registering BackgroundSyncPlugin:

workbox.routing.registerRoute(new RegExp(' /\/php\/postPO.php/'),
                                          ^

Maybe you can try with:

workbox.routing.registerRoute(/\/php\/postPO\.php/,
  new workbox.strategies.NetworkOnly({
    plugins: [
      new workbox.backgroundSync.BackgroundSyncPlugin('po-data-queue', {
        maxRetentionTime: 2 * 24 * 60 // two days
      })
    ]
  }),
 'POST'
);

The above will work for any URL that contains /php/postPO.php. You can test it here.

The official docs here showcase some examples and how to test if the background sync is actually working.

Upvotes: 1

Related Questions