-
-
Save rmehner/b9a41d9f659c9b1c3340 to your computer and use it in GitHub Desktop.
// Credit to @steobrien from https://gist.github.com/rmehner/b9a41d9f659c9b1c3340#gistcomment-2940034 | |
// for modern browsers, this works: | |
const dbs = await window.indexedDB.databases() | |
dbs.forEach(db => { window.indexedDB.deleteDatabase(db.name) }) | |
// for older browsers, have a look at previous revisions of this gist. |
❤️
mad props
so sad that this is broken now
up-to-date version:
const dbs = await window.indexedDB.databases()
dbs.forEach(db => { window.indexedDB.deleteDatabase(db.name) })
Unfortunately the above is not currently implemented in Firefox or Safari, see https://developer.mozilla.org/en-US/docs/Web/API/IDBFactory/databases
@alexmi256: Have a look at what @steobrien posted just above your comment: https://gist.github.com/rmehner/b9a41d9f659c9b1c3340#gistcomment-2940034
I'll update the main gist to reflect those changes.
The version posted by @steobrien is what I was referring to, the databases()
function of indexed DB is only supported by Chrome, Edge, Opera. Safari and Firefox do not support it.
@alexmi256 you're right. Any workaround for Firefox and Safari?
@alexmi256 @frederikhors AFAIK there's no way to do this in Firefox.
For Safari, you might get lucky by using the previous version of this gist: https://gist.github.com/rmehner/b9a41d9f659c9b1c3340/c7971d082a04a8f47ec496e7eefa5521af2f1577
Just double checked, with current Safari it also not working anymore. databases()
not being in the spec is probably the reason for it.
Is there anything wrong if I use:
window.indexedDB.deleteDatabase('myDB')
?
No, this is the right way to delete a indexedDB database. The code above actually used that method as well. The difference is, that the gist gets all databases in the current scope and deletes them using the line you've posted.
@NimaSoroush Problem is that Firefox and Safari both do not supported the databases
method on the indexedDB
instance and therefore this can't work. Or did something change?
ah right, missed that point
/**
* Polyfill for indexedDB.databases()
* Safari and some other older browsers that support indexedDB do NOT
* Support enumerating existing databases. This is problematic when it
* comes time to cleanup, otherwise we could litter their device with
* unreferenceable database handles forcing a nuclear browser clear all history.
*/
(function () {
if (window.indexedDB && typeof window.indexedDB.databases === 'undefined') {
const LOCALSTORAGE_CACHE_KEY = 'indexedDBDatabases';
// Store a key value map of databases
const getFromStorage = () =>
JSON.parse(window.localStorage[LOCALSTORAGE_CACHE_KEY] || '{}');
// Write the database to local storage
const writeToStorage = value =>
(window.localStorage[LOCALSTORAGE_CACHE_KEY] = JSON.stringify(value));
IDBFactory.prototype.databases = () =>
Promise.resolve(
Object.entries(getFromStorage()).reduce((acc, [name, version]) => {
acc.push({ name, version });
return acc;
}, [])
);
// Intercept the existing open handler to write our DBs names
// and versions to localStorage
const open = IDBFactory.prototype.open;
IDBFactory.prototype.open = function (...args) {
const dbName = args[0];
const version = args[1] || 1;
const existing = getFromStorage();
writeToStorage({ ...existing, [dbName]: version });
return open.apply(this, args);
};
// Intercept the existing deleteDatabase handler remove our
// dbNames from localStorage
const deleteDatabase = IDBFactory.prototype.deleteDatabase;
IDBFactory.prototype.deleteDatabase = function (...args) {
const dbName = args[0];
const existing = getFromStorage();
delete existing[dbName];
writeToStorage(existing);
return deleteDatabase.apply(this, args);
};
}
})();
So how do Firefox Web-developer tools list the databases?
There must be something for this to work.
@ray007 good idea, the source code of this is actually open source, maybe you find something there: https://github.com/firefox-devtools
Would be useful indeed!
Here's a condensed one-liner if you just want something to copy and paste into your browser console:
indexedDB.databases().then(dbs => dbs.forEach(db => indexedDB.deleteDatabase(db.name)))
Safari DOES have indexedDb.databases, but can't do await
from the console. Luckily the abovementioned .then(dbs => dbs.forEach...)
is enough, since the oh so perfect Apple User interface requires you do delete EACH COLLECTION (instead of each database) and to do that you have to move the pointer to the other side of the window and click the trashcan button.
Firefox implements it only in webworkers so I guess it'll still be a lot of right-click-deletes (at least much faster than in Safari) unless you implement a helper function in a web worker (that HAS to be downloaded from the server).
Oh and if you think this means Chrome has a better implementation of indexedDbs, think again: it's significantly slower than both FF and Safari.... #webstandardsssuck #sorryfortherant
Sadly it doesn't work in Firefox Web Workers either, even if everyone says it does.. :(
const workFunc = function (data) {
const idd = indexedDB
|| webkitIndexedDB
|| mozIndexedDB;
const deletedDbs = [];
idd.databases()
.then(dbs => dbs.forEach(db => {idd.deleteDatabase(db.name); deletedDbs.push(db.name);}))
.then(function () {self.postMessage(deletedDbs)});
};
worker = new Worker(URL.createObjectURL(new Blob(["onmessage =" + workFunc.toString()], {type: "text/javascript"})));
worker.onmessage = function (deletedDbs) {
console.log('Deleted databases: '+ deletedDbs.join(','));
};
worker.onerror = function (e) {
console.log('Error? What error?', e.message, '. Oh that one!');
};
worker.postMessage('testing')
Remember to wrap the execution in an async
function.
(async () => {
const dbs = await window.indexedDB.databases();
dbs.forEach(db => { window.indexedDB.deleteDatabase(db.name) });
})();
This works fine for me on Safari. Note that you may not see the effect immediately on the dev tool until you close the browser window and open it again.
🙏🏽
Here's a condensed one-liner if you just want something to copy and paste into your browser console:
indexedDB.databases().then(dbs => dbs.forEach(db => indexedDB.deleteDatabase(db.name)))
Just commenting so that I can always find this.
cool, better than digging through the chrome settings page. #thx