I setup my service worker to show update notification to the user after update. But the notification dialog is not showing up. What I am doing wrong?
registerValidSW function in serviceWorker.js
function registerValidSW(swUrl, config) {
navigator.serviceWorker
.register(swUrl)
.then(registration => {
registration.update();
setInterval(() => {
registration.update();
console.debug("Checked for update...");
}, (1000 * 60) * 30);
registration.onupdatefound = () => {
const installingWorker = registration.installing;
if (installingWorker == null) {
return;
}
installingWorker.onstatechange = () => {
if (installingWorker.state === 'installed') {
if (navigator.serviceWorker.controller) {
console.log(
'New content is available and will be used when all ' +
'tabs for this page are closed.'
);
<ReleaseDialog />
if (config && config.onUpdate) {
config.onUpdate(registration);
}
} else {
console.log('Content is cached for offline use.');
if (config && config.onSuccess) {
config.onSuccess(registration);
}
}
}
};
};
})
.catch(error => {
console.error('Error during service worker registration:', error);
});
let refreshing = false;
navigator.serviceWorker.addEventListener('controllerchange', () => {
if (refreshing) {
return;
}
refreshing = true;
console.log("controller change")
window.location.reload();
});
}
index.js
serviceWorker.register({
onUpdate: async function (registration) {
const waitingServiceWorker = registration.waiting
const bc = new BroadcastChannel('app-update');
bc.postMessage('App has updated.');
}
});
dialog component:
class ReleaseDialog extends React.Component {
state = {
open: false,
};
componentWillMount = () => {
if (typeof BroadcastChannel !== 'undefined') {
const updateChannel = new BroadcastChannel('app-update');
updateChannel.addEventListener('message', event => {
this.setState({open: true})
});
}
}
handleAccept = async () => {
try {
if (navigator && navigator.serviceWorker) {
const waitingServiceWorker = await navigator.serviceWorker.ready
if (waitingServiceWorker.waiting) {
waitingServiceWorker.waiting.postMessage({type: "SKIP_WAITING"});
}
}
} catch (e) {
console.error(e)
}
}
handleClose = () => {
this.setState({open: false});
};
render() {
return (
<div>
<Dialog
open={this.state.open}
onClose={this.handleClose}
>
<DialogTitle id="alert-dialog-title">New Version is Available!</DialogTitle>
<DialogActions>
<Button onClick={this.handleClose} color="default">
Cancel
</Button>
<Button onClick={this.handleAccept} color="primary" autoFocus={true}>
UPDATE
</Button>
</DialogActions>
</Dialog>
</div>
)
}
}
export default ReleaseDialog;
service-worker.js
self.addEventListener('message', (e) => {
if (e.data && e.data.type === 'SKIP_WAITING') {
self.skipWaiting();
}
});
Please note that I am using workbox, PWA with CRA. To force update I use to change the name of my cache with numbers. But when I load the page I am not getting the notification dialog to force the service worker to activate the new one.