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
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.