Fix #5 serviceWorker DB access

serviceWorker openes DB only when needed and closes it directly
This commit is contained in:
Timon Ostertun
2020-09-30 16:46:10 +02:00
parent 0fb1bb0462
commit 12c1a614bb

View File

@@ -1,9 +1,9 @@
<?php <?php
header('Content-Type: text/javascript'); header('Content-Type: text/javascript');
require_once(__DIR__ . '/server/config.php'); require_once(__DIR__ . '/server/config.php');
?> ?>
importScripts('https://storage.googleapis.com/workbox-cdn/releases/5.1.2/workbox-sw.js'); importScripts('https://storage.googleapis.com/workbox-cdn/releases/5.1.2/workbox-sw.js');
@@ -41,7 +41,7 @@ workbox.precaching.precacheAndRoute([
return $hash; return $hash;
} }
$hash = md5(getDirHash(__DIR__)); $hash = md5(getDirHash(__DIR__));
$path = __DIR__ . '/server/content/'; $path = __DIR__ . '/server/content/';
$dir = opendir($path); $dir = opendir($path);
while ($file = readdir($dir)) { while ($file = readdir($dir)) {
@@ -50,7 +50,7 @@ workbox.precaching.precacheAndRoute([
echo "\t{url: '$file', revision: '$hash'},\n"; echo "\t{url: '$file', revision: '$hash'},\n";
} }
closedir($dir); closedir($dir);
// ASSETS // ASSETS
$filesToCache = [ $filesToCache = [
'/manifest.json.php', '/manifest.json.php',
@@ -58,7 +58,7 @@ workbox.precaching.precacheAndRoute([
$dirsToCache = [ $dirsToCache = [
'/client', '/client',
]; ];
function addDir($path) { function addDir($path) {
global $filesToCache; global $filesToCache;
if ($dir = opendir(__DIR__ . $path)) { if ($dir = opendir(__DIR__ . $path)) {
@@ -74,11 +74,11 @@ workbox.precaching.precacheAndRoute([
closedir($dir); closedir($dir);
} }
} }
foreach ($dirsToCache as $path) { foreach ($dirsToCache as $path) {
addDir($path); addDir($path);
} }
foreach ($filesToCache as $file) { foreach ($filesToCache as $file) {
$revision = md5_file(__DIR__ . $file); $revision = md5_file(__DIR__ . $file);
$file = SERVER_ADDR . $file; $file = SERVER_ADDR . $file;
@@ -109,30 +109,41 @@ workbox.routing.registerRoute(
// DB // DB
var db = null; function openDb() {
if (indexedDB) { return new Promise(function(resolve) {
var request = indexedDB.open('regatten_app_db_<?php echo BOATCLASS; ?>'); if (indexedDB) {
request.onerror = function (e) { var request = indexedDB.open('regatten_app_db_<?php echo BOATCLASS; ?>');
console.log('[sW] Cannot open DB:', e.target.errorCode); request.onerror = function (e) {
}; console.log('[sW] Cannot open DB:', e.targer.errorCode);
request.onupgradeneeded = function (e) { resolve(null);
console.log('[sW] DB does not exist'); };
e.target.transaction.abort(); request.onupgradeneeded = function (e) {
}; console.log('[sW] DB does not exist');
request.onsuccess = function (e) { e.target.transaction.abort();
console.log('[sW] DB loaded'); resolve(null);
db = e.target.result; };
db.onerror = function (e) { request.onsuccess = function (e) {
console.log('[sW] DB Error:', e) console.log('[sW] DB loaded');
var db = e.target.result;
db.onerror = function (e) {
console.log('[sW] DB Error:', e);
};
resolve(db);
}
} else {
resolve(null);
} }
}; });
} }
function dbSettingsGet(key) { function dbSettingsGet(key) {
return new Promise(function(resolve) { return new Promise(async function(resolve) {
if (db != null) { var db = await openDb();
if (db !== null) {
var request = db.transaction('settings').objectStore('settings').get(key); var request = db.transaction('settings').objectStore('settings').get(key);
request.onsuccess = function (event) { request.onsuccess = function (event) {
db.close();
console.log('[sW] DB closed');
resolve(typeof request.result != 'undefined' ? request.result.value : null); resolve(typeof request.result != 'undefined' ? request.result.value : null);
} }
} else { } else {
@@ -141,10 +152,20 @@ function dbSettingsGet(key) {
}); });
} }
function dbSettingsSet(key, value) { async function dbSettingsSet(key, value) {
var db = await openDb();
if (db != null) { if (db != null) {
var os = db.transaction('settings', 'readwrite').objectStore('settings'); var os = db.transaction('settings', 'readwrite').objectStore('settings');
os.put({ key: key, value: value}); var request = os.put({ key: key, value: value});
request.onerror = function (event) {
console.log('[sW] Error while saving data to DB:', e);
db.close();
console.log('[sW] DB closed');
}
request.onsuccess = function (event) {
db.close();
console.log('[sW] DB closed');
}
} }
} }
@@ -167,7 +188,7 @@ function isMyRegatta(id) {
self.addEventListener('push', async function(event) { self.addEventListener('push', async function(event) {
console.log('[sW] Push received:', event.data.text()); console.log('[sW] Push received:', event.data.text());
var data; var data;
try { try {
data = JSON.parse(event.data.text()); data = JSON.parse(event.data.text());
@@ -175,14 +196,14 @@ self.addEventListener('push', async function(event) {
console.log(e); console.log(e);
data = undefined; data = undefined;
} }
if (typeof data.type !== "undefined") { if (typeof data.type !== "undefined") {
switch (data.type) { switch (data.type) {
case 'notification': case 'notification':
if (typeof data.title === "undefined") break; if (typeof data.title === "undefined") break;
if (typeof data.body === "undefined") break; if (typeof data.body === "undefined") break;
if (typeof data.channel === "undefined") break; if (typeof data.channel === "undefined") break;
// check channel // check channel
var okay = false; var okay = false;
switch (data.channel) { switch (data.channel) {
@@ -214,7 +235,7 @@ self.addEventListener('push', async function(event) {
console.log('Notification channel not subscribed'); console.log('Notification channel not subscribed');
return; return;
} }
const options = { const options = {
data: data, data: data,
body: data.body, body: data.body,
@@ -225,26 +246,63 @@ self.addEventListener('push', async function(event) {
if ((image = getEntry(data, 'image', null)) !== null) { if ((image = getEntry(data, 'image', null)) !== null) {
options.image = image; options.image = image;
} }
// Force refresh on next app open // Force refresh on next app open
var os = db.transaction('update_times', 'readwrite').objectStore('update_times'); var db = await openDb();
os.put({ table: 'last_sync', time: 0 }); if (db != null) {
var os = db.transaction('update_times', 'readwrite').objectStore('update_times');
var request = os.put({ table: 'last_sync', time: 0 });
request.onerror = function (event) {
console.log('[sW] Error while saving data to DB:', e);
db.close();
console.log('[sW] DB closed');
}
request.onsuccess = function (event) {
db.close();
console.log('[sW] DB closed');
}
}
console.log('Showing notification'); console.log('Showing notification');
self.registration.showNotification(data.title, options); self.registration.showNotification(data.title, options);
break; break;
case 'forcesync':
// Force refresh on next app open
var db = await openDb();
if (db != null) {
var os = db.transaction('update_times', 'readwrite').objectStore('update_times');
var request = os.put({ table: 'last_sync', time: 0 });
request.onerror = function (event) {
console.log('[sW] Error while saving data to DB:', e);
db.close();
console.log('[sW] DB closed');
}
request.onsuccess = function (event) {
console.log('[sW] Data successfully saved');
db.close();
console.log('[sW] DB closed');
}
}
break;
default:
console.log('[sW] Push type unknown:', data.type);
break;
} }
} else {
console.log('[sW] No push type given!');
} }
}); });
self.addEventListener('notificationclick', function(event) { self.addEventListener('notificationclick', function(event) {
var data = event.notification.data; var data = event.notification.data;
event.notification.close(); event.notification.close();
var url = '<?php echo SERVER_ADDR; ?>' + getEntry(data, 'url', ''); var url = '<?php echo SERVER_ADDR; ?>' + getEntry(data, 'url', '');
event.waitUntil( event.waitUntil(
clients.openWindow(url) clients.openWindow(url)
); );
}); });