1

Ok, so I'm trying to make an Angular 7 PWA that uses background sync.

I can trigger the sync event from within the dev tools in Chromium but it won't trigger when I remove my ethernet cable and plug it back in.

I originally thought it was my service worker file being odd so I added this: https://stackoverflow.com/a/50414028/9978023 , what's weird is that it works in Firefox but not Chromium. So using this I can trigger the same function that the sync event is meant to call. But it's not a great solution.

self.addEventListener('sync', function (event) {
  console.log('I heard a sync event. Sending Posts to server', event);
  event.waitUntil(sendPostsToServer()
    .then(res => {
      console.log(res);
    })
    .catch(e=>{console.log(e)}));
});


async function sendPostsToServer() {
  // POST to server
}

service-worker.js

What am I doing wrong? Why isn't the sync event triggering when I reconnected to the Internet?

nichh
  • 41
  • 4

2 Answers2

2

I figured out what was going on. I had to manually tell the Service Worker to trigger the sync event when it was back online with:

navigator.serviceWorker.ready.then(function (swRegistration) {
     return swRegistration.sync.register('myFirstSync');
});

With this (which i run when the POST is unsuccessful) the SW will run trigger the sync event when we're back online.

P.S. This will only trigger the event once:

If you go back online after running the code above it will trigger but if you go back off and back on afterwards it will not trigger again. So this code needs to be ran every time you want the background sync to work.

nichh
  • 41
  • 4
0

Request a sync

The first thing to do is to request a sync. This can be done by your app frontend or your service worker.

  • Requesting the sync from the frontend is good when you want to leave the user in charge of synchronizing later or not.
  • Requesting the sync from the service worker is good when you want this to be transparent to the user. In this case, the service worker can detect the failed fetch request and request the sync right away.

To request a sync, you need a ServiceWorkerRegistration and a tag name. From the app frontend code, do the following:

async function requestBackgroundSync() {
    const registration = await navigator.serviceWorker.ready;
    await registration.sync.register('my-tag-name');
}

Or, from the service worker, do this instead:

async function requestBackgroundSync() {
    await self.registration.sync.register('my-tag-name');
}

The my-tag-name string above should be a unique tag that identifies this sync request, so that multiple requests can be done.

risingagain
  • 210
  • 2
  • 12