Monday, March 15, 2021

Notification using Service Worker Example

 


How to create notification using Service Worker?

Let's follow the code below :

index.html

<!--
	Notification using Service Worker Example
	-----------------------------------

	Step 1 : Create file index.html & sw.js
	Step 2 : You need to run this app at http://{host}
	Step 3 : Done

	-----------------------------------

	Reference :
		- https://developers.google.com/web/fundamentals/primers/service-workers
		- https://stackoverflow.com/a/33705250/9278668
		- https://stackoverflow.com/a/31480604/9278668
		- https://serviceworke.rs/push-clients_service-worker_doc.html
		- https://css-tricks.com/creating-scheduled-push-notifications/
		- https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration/showNotification
		- https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerGlobalScope/message_event
-->
<html>
<head>
	<title>Notification using Service Worker Example</title>
</head>
<body>
	<h1>Notification using Service Worker Example</h1>

	<button onclick="installServiceWorker()">Install Service Worker</button>
	<button onclick="uninstallServiceWorker()">Uninstall Service Worker</button>
	<button onclick="inspectServiceWorker()">Inspect Service Worker</button>

	<button onclick="showNotification()">Show Notification</button>
	<button onclick="closeAllNotifications()">Close All Notifications</button>

	<br /><br />

	Open : <a href="chrome://inspect/#service-workers">chrome://inspect/#service-workers</a> for <b>inspect</b> <i>service worker</i> in google chrome

</body>
</html>

<script type="text/javascript">
function installServiceWorker() {
	if('serviceWorker' in navigator) {
		// Install Service Worker
		navigator.serviceWorker.register('./sw.js').then(function(registration) {
			console.log('[BROWSER] - Service worker registration successful with scope : ' + registration.scope);
		}, function(err) {
			console.error('[BROWSER] - Service worker registration failed :', err);
		});

		// Init to listen incoming message from service worker
		navigator.serviceWorker.addEventListener('message', function(event) {
			console.log('Event : ', event);
			console.log('postMessage : ', event.data);

			alert("Message from Service Worker :\n\n" + "postMessage : " + event.data + "\n\n" + "Event : " + JSON.stringify(event));
		});
	}
}
function uninstallServiceWorker() {
	if('serviceWorker' in navigator) {
		navigator.serviceWorker.getRegistrations().then(function(registrations) {
			for(let registration of registrations) {
				console.log('[BROWSER] - Uninstalled service worker successful.', registration);
				registration.unregister();
			} 
		});
	}
}
function inspectServiceWorker() {
	alert('Open -> chrome://inspect/#service-workers');
	window.location = 'chrome://inspect/#service-workers';
}
async function showNotification(title, body) {
	const reg = await navigator.serviceWorker.getRegistration();
	Notification.requestPermission().then(function(permission) {
		if (permission !== 'granted') {
			alert('You need to allow push notifications');
		}
		else {
			reg.showNotification(
				'Demo Push Notification', {
					tag: 'my-simple-notification-sw', // a unique ID
					body: 'Hello World', // content of the message notification
					data: {
						url: window.location.href, // pass the current url to the notification
					},
					badge: 'http://ahmbcode.id/img/logo.png',
					icon: 'http://ahmbcode.id/img/logo.png',
					image: 'http://ahmbcode.id/img/logo.png',
					vibrate: [500, 300, 500],
					silent: false,
					actions: [
						{
							action: 'open_google',
							title: 'Open Google',
							//icon:'http://ahmbcode.id/img/logo.png'
						},
						{
							action: 'open_gmail',
							title: 'Open Gmail',
							//icon:'http://ahmbcode.id/img/logo.png'
						}
					]
				}
			);
		}
	});
}

function closeAllNotifications() {
	navigator.serviceWorker.getRegistration().then(function(registration){
		registration.getNotifications().then(function(notifications){
			notifications.forEach(function(notification){
				notification.close();
			});
		});
	});
}
</script>

sw.js

self.addEventListener('install', function(event) {
	console.log('[SERVICE-WORKER] - Service worker installed successful.');
	event.waitUntil(self.skipWaiting());
});

self.addEventListener('activate', function(event) {
	console.log('[SERVICE-WORKER] - Service worker activated');
	event.waitUntil(self.clients.claim());
});

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

	console.log('[SERVICE-WORKER] - Notification Action : ', event.action);
	console.log('[SERVICE-WORKER] - Notification Data   : ', event.notification.data);

	// event.notification.close();

	if(event.action === 'open_google') {
		openPage('https://www.google.com', event);
	}
	else if(event.action === 'open_gmail') {
		openPage('https://mail.google.com', event);
	}
});

// Check the browser for update the current tab or open new tab
function openPage(url, event) {
	event.waitUntil(
		self.clients.matchAll().then(function(clientList) {
			
			if (clientList.length > 0) { // If Tab is currently open

				clientList[0].postMessage('Opening -> ' + url);	// Send data to Window

				clientList[0].navigate(url);		// Redirect URL in current tab
				return clientList[0].focus();		// Focus in current tab
			}

			// If Tab are closed
			return self.clients.openWindow(url);
		})
	);
}


You  need run this app on http://{host} .

For developer tools, you can inspect the service workers at chrome://inspect/#service-workers


Reference :


How to Cache, Fetch Files & Remove Old Caches on Service Worker Example


How to cache, fetch files & remove old cache on service worker?

Let's follow the code below :

index.html

<!--
	Cache & Fetch Files on Service Worker Example
	-----------------------------------

	Step 1 : Create file index.html & sw.js
	Step 2 : Put the file you want to cache
	Step 3 : You need to run this app at http://{host}
	Step 4 : Done

	-----------------------------------

	Reference :
		- https://developers.google.com/web/fundamentals/primers/service-workers
		- https://stackoverflow.com/a/33705250/9278668
		- https://stackoverflow.com/q/46865552/9278668
		- https://kotakode.com/pertanyaan/1556/mengatasi-uncaught-(in-promise)-typeerror%3A-request-failed-pada-web-pwa
-->
<html>
<head>
	<title>Cache & Fetch Files on Service Worker Example</title>
</head>
<body>
	<h1>Cache & Fetch Files on Service Worker Example</h1>

	<button onclick="installServiceWorker()">Install & Init Cache on Service Worker</button>
	<button onclick="uninstallServiceWorker()">Uninstall Service Worker</button>
	<button onclick="inspectServiceWorker()">Inspect Service Worker</button>

	<br /><br />

	Open : <a href="chrome://inspect/#service-workers">chrome://inspect/#service-workers</a> for <b>inspect</b> <i>service worker</i> in google chrome

	<br /><br />

	<img src="sw-lifecycle.png"> <br /> 
	<img src="sw-cache-lifecycle.jpg" width="500"> <br /> 
	<img src="img/service-worker.png"> <br /> 
</body>
</html>

<script type="text/javascript">
function installServiceWorker() {
	if('serviceWorker' in navigator) {
		navigator.serviceWorker.register('./sw.js').then(function(registration) {
			console.log('[BROWSER] - Service worker registration successful with scope : ' + registration.scope);
		}, function(err) {
			console.error('[BROWSER] - Service worker registration failed :', err);
		});
	}
}
function uninstallServiceWorker() {
	if('serviceWorker' in navigator) {
		navigator.serviceWorker.getRegistrations().then(function(registrations) {
			for(let registration of registrations) {
				console.log('[BROWSER] - Uninstalled service worker successful.', registration);
				registration.unregister();
			} 
		});
	}
}
function inspectServiceWorker() {
	alert('Open -> chrome://inspect/#service-workers');
	window.location = 'chrome://inspect/#service-workers';
}
</script>

sw.js

const CACHE_NAME = 'webapp-v1';
const CACHE_FILES = [
	'/sw-lifecycle.png',
	'/sw-cache-lifecycle.jpg'
];

self.addEventListener('install', event => {
	console.log('[SERVICE-WORKER] - Service worker installed successful.');
	event.waitUntil(
		caches.open(CACHE_NAME)
			.then(cache => cache.addAll(CACHE_FILES))
			.then(self.skipWaiting())
			.catch(err => console.error('[SERVICE-WORKER] - Error trying to pre-fetch cache files :', err))
	);
});

self.addEventListener("activate", (event) => {
	console.log('[SERVICE-WORKER] - Service worker activated');
	// delete if cache name is undeclared
	event.waitUntil(
		caches.keys().then((cacheFiles) => {
			return Promise.all(
				cacheFiles.map((cache) => {
					if (cache !== CACHE_NAME) {
						console.log('[SERVICE-WORKER] - Clearing old cache :', cache);
						return caches.delete(cache);
					}
				})
			);
		})
	);
});

self.addEventListener('fetch', event => {
	if (!event.request.url.startsWith(self.location.origin)) return;
	console.log('[SERVICE-WORKER] - Fetch event on :', event.request.url);
	event.respondWith(
		caches.match(event.request).then(response => {
			console.info('[SERVICE-WORKER] - Responded to ', event.request.url, 'with', response ? 'cache hit.' : 'fetch.');
			return response || fetch(event.request);
		}).catch(err => {
			console.error('[SERVICE-WORKER] - Error with match or fetch:', err);
		})
	);
});


You  need run this app on http://{host} .

For developer tools, you can inspect the service workers at chrome://inspect/#service-workers


Reference :


Service Worker Install & Uninstall Example


 

How to install & uninstall service worker programmatically?

Let's follow the code below:

Install

function installServiceWorker() {
	if('serviceWorker' in navigator) {
		navigator.serviceWorker.register('./sw.js').then(function(registration) {
			console.log('[BROWSER] - Service worker registration successful with scope : ' + registration.scope);
		}, function(err) {
			console.error('[BROWSER] - Service worker registration failed :', err);
		});
	}
}

Uninstall

function uninstallServiceWorker() {
	if('serviceWorker' in navigator) {
		navigator.serviceWorker.getRegistrations().then(function(registrations) {
			for(let registration of registrations) {
				console.log('[BROWSER] - Uninstalled service worker successful.', registration);
				registration.unregister();
			} 
		});
	}
}

sw.js

self.addEventListener('install', function(event) {
	console.log('[SERVICE-WORKER] - Service worker installed');
});

self.addEventListener('activate', function(event) {
	console.log('[SERVICE-WORKER] - Service worker activated');
	event.waitUntil(self.clients.claim());
});

index.html

<!--
	Service Worker: Install & Uninstall Example
	-----------------------------------

	Step 1 : Create file index.html & sw.js
	Step 2 : You need to run this app at http://{host}
	Step 3 : Done

	-----------------------------------

	Reference :
		- https://developers.google.com/web/fundamentals/primers/service-workers
		- https://stackoverflow.com/a/33705250/9278668
-->
<html>
<head>
	<title>Service Worker: Install & Uninstall Example</title>
</head>
<body>
	<h1>Service Worker: Install & Uninstall Example</h1>

	<button onclick="installServiceWorker()">Install Service Worker</button>
	<button onclick="uninstallServiceWorker()">Uninstall Service Worker</button>
	<button onclick="inspectServiceWorker()">Inspect Service Worker</button>

	<br /><br />

	Open : <a href="chrome://inspect/#service-workers">chrome://inspect/#service-workers</a> for <b>inspect</b> <i>service worker</i> in google chrome

	<br /><br />

	<img src="sw-lifecycle.png">
</body>
</html>

<script type="text/javascript">
function installServiceWorker() {
	if('serviceWorker' in navigator) {
		navigator.serviceWorker.register('./sw.js').then(function(registration) {
			console.log('[BROWSER] - Service worker registration successful with scope : ' + registration.scope);
		}, function(err) {
			console.error('[BROWSER] - Service worker registration failed :', err);
		});
	}
}
function uninstallServiceWorker() {
	if('serviceWorker' in navigator) {
		navigator.serviceWorker.getRegistrations().then(function(registrations) {
			for(let registration of registrations) {
				console.log('[BROWSER] - Uninstalled service worker successful.', registration);
				registration.unregister();
			} 
		});
	}
}
function inspectServiceWorker() {
	alert('Open -> chrome://inspect/#service-workers');
	window.location = 'chrome://inspect/#service-workers';
}
</script>


You  need run this app on http://{host} .

For developer tools, you can inspect the service workers at chrome://inspect/#service-workers


Reference :