Service workers "sync" operation is working while its offline?

Viewed 193

I have a PWA project where I send the data to server. During this process, if the user is offline then the data is stored in indexedDb and a sync tag is registered. So, then when the user comes online that data can sent to the server. But In my case the sync event gets executed immediately when the we register a sync event tag, which means the data is tried to be sent to server while its offline, which is not going to work.

I think the sync event supposed to fire while its online only, what could be issue here ?

The service worker's sync event works accordingly when I tried to enable and disable the offline option of chrome devtools, and also works correctly in my android phone.

This is how I register my sync tag

function onFailure() {
    var form = document.querySelector("form");

    //Register the sync on post form error
    if ('serviceWorker' in navigator && 'SyncManager' in window) {
        navigator.serviceWorker.ready
            .then(function (sw) {
                var post = {
                    datetime1: form.datetime1.value,
                    datetime: form.datetime.value,
                    name: form.name.value,
                    image: form.url.value,
                    message: form.comment.value
                };
                writeData('sync-comments', post)
                    .then(function () {
                        return sw.sync.register('sync-new-comment');
                    })
                    .then(function () {
                        console.log("[Sync tag registered]");
                    })
                    .catch(function (err) {
                        console.log(err);
                    });
            });
    }
}

And this is how the sync event is called

self.addEventListener('sync', function (event) {

    console.log("[Service worker] Sync new comment", event);
    if (event.tag === 'sync-new-comment') {
        event.waitUntil(
            readAllData('sync-comments')
                .then(function (data) {
                    setTimeout(() => {
                        data.forEach(async (dt) => {

                            const url = "/api/post_data/post_new_comment";
                            const parameters = {
                                method: 'POST',
                                headers: {
                                    'Content-Type': "application/json",
                                    'Accept': 'application/json'
                                },
                                body: JSON.stringify({
                                    datetime: dt.datetime,
                                    name: dt.name,
                                    url: dt.image,
                                    comment: dt.message,
                                    datetime1: dt.datetime1,
                                })
                            };

                            fetch(url, parameters)
                                .then((res) => {
                                    return res.json();
                                })
                                .then(response => {
                                    if (response && response.datetimeid) deleteItemFromData('sync-comments', response.datetimeid);
                                }).catch((error) => {
                                    console.log('[error post message]', error.message);
                                })
                        })
                    }, 5000);
                })
        );
    }
});
1 Answers

you mention

The service worker's sync event works accordingly when I tried to enable and disable the offline option of chrome devtools, and also works correctly in my android phone.

So I'm not sure which case is the one failing.

You are right that the sync will be triggered when the browser thinks the user is online, if the browser detects that the user is online at the time of the sync registration it will trigger the sync:

In true extensible web style, this is a low level feature that gives you the freedom to do what you need. You ask for an event to be fired when the user has connectivity, which is immediate if the user already has connectivity. Then, you listen for that event and do whatever you need to do.

Also, from the workbox documentation

Browsers that support the BackgroundSync API will automatically replay failed requests on your behalf at an interval managed by the browser, likely using exponential backoff between replay attempts.

Related