Skip to main content
2 of 5
added 252 characters in body

sync event not firing when user goes online

I'm trying to sync offline data with the server after a user comes back online. I'm trying to follow these steps that I have found doing research on this. This information I'm using as a guide. BTW, I'm new to this, so I'm still trying to figure out the logic flow of everything.

To sync IndexedDB to a server in the background using service workers, you can use the background sync feature of service workers. This feature allows you to defer actions until the user has stable connectivity. Here are the steps to follow:

Register a service worker in your application’s JavaScript file using feature detection. You can use the following code snippet: JavaScript AI-generated code. Review and use carefully. More info on FAQ.
I have this function in my app.js file and it is called at the bottom of every page for offline capabilities

if (navigator.serviceWorker) { navigator.serviceWorker.register('serviceworker.js'); } 

In your service worker, add an event listener for the sync event. This event is triggered when the user has stable connectivity. You can use the following code snippet: JavaScript AI-generated code. Review and use carefully. More info on FAQ.
I have this function in my sw.js file

self.addEventListener('sync', function(event) { if (event.tag === 'sync_date_time') { console.log('sync event has been fired'); // event.waitUntil(syncData()); } }); 

In the syncData function, retrieve the data from IndexedDB and send it to the server using the fetch API. You can use the following code snippet: JavaScript AI-generated code. Review and use carefully. More info on FAQ.
This is the easy part, just sending the information to the server that I get pulled from IndexedDB. Although my function will be a little different

function syncData() { return getIndexedDBData().then(function(data) { return fetch('/sync', { method: 'POST' body: JSON.stringify(data), headers: {'Content-Type': 'application/json'} }); }); } 

In your application’s frontend code, request a sync by calling the register() method on the SyncManager interface. You can use the following code snippet: JavaScript AI-generated code. Review and use carefully. More info on FAQ.
This function I have in my dateTimeJS.js file.

async function requestBackgroundSync() { const registration = await navigator.serviceWorker.ready; await registration.sync.register(BACKGROUND_QUERY_DATE_TIME); } 

Finally, handle the sync event in your server-side code and update the server-side database with the data sent from the client.

I have my sw registered, I have the function requestBackgroundSync in the js file that is loaded with page that has the form. Here is my dateTime.js file:

const BACKGROUND_QUERY_DATE_TIME = 'sync_date_time'; const IDB = function init() { let db = null; let DBOpenReq = indexedDB.open('dateTimeDB',1); DBOpenReq.addEventListener('success', evt => { db = evt.target.result; }); DBOpenReq.addEventListener('upgradeneeded', evt => { db = evt.target.result; const objectStore = db.createObjectStore('date_time',{ autoIncrement: true }) }) let form = document.getElementById('date_time_form'); form.addEventListener('submit', async evt => { evt.preventDefault(); let fm = document.getElementById('form_msg'); fm.innerHTML = ''; const data = new FormData(form); const formData = Object.fromEntries(data.entries()); let userData = { uID: formData.uID, tz: formData.time_zone, tf: formData.time_format, df: formData.date_format } try{ const req = await fetch('../date-time-format/src/inc/dateTimeAPI.php',{ method: 'POST', headers: {'Content-Type':'application/json'}, body: JSON.stringify(userData) }); const res = await req.json(); if(res.status === 'ok'){ fm.classList.remove('w3-text-red'); fm.classList.add('w3-text-green'); fm.innerHTML = res.msg; } else if(res.status === 'error'){ fm.classList.remove('w3-text-green'); fm.classList.add('w3-text-red'); fm.innerHTML = res.msg; } } catch{ // Clear any data previously saved in the store clearStore(db,'date_time'); let tx = db.transaction('date_time','readwrite'); let store = tx.objectStore('date_time'); let req = store.add(userData); req.onsuccess = evt => { fm.classList.remove('w3-text-red'); fm.classList.add('w3-text-green'); fm.innerHTML = 'Date/Time Options have been set.'; } } }) } async function requestBackgroundSync() { const registration = await navigator.serviceWorker.ready; await registration.sync.register(BACKGROUND_QUERY_DATE_TIME); } IDB(); requestBackgroundSync(); 

When I go to the page with the form, I use the devTools to go into offline mode. This puts the form data into the IndexedDB after the form submission. This works as expected. Then I click on the checkbox to make the page be "online" but nothing happens. I would expect that the console.log would fire to let me know that there was a sync event.

I'm sure there is something simple that I am missing but I have not yet run across a solution to my problem.

Question What am I missing to have the sync event fire when I bring the browser back online?

I have found these questions. The first link had no answers. The second question was of no help either. Then I found the third link here and I tried to follow how they implemented the sync, but it is still not firing.

When and how are sync events fired in service workers?
Background sync not firing event in serviceworker
Call Back not fired when listening to 'sync' event in service worker

If ya'll need more information/code, please let me know.

Just an Update
In the devTools I started recording background sync events. I used the "sync" button with the tag name under the "service worker" to try to trigger the sync event. Nothing happened. No indication of the sync event being fired.