deleteFromDisk-Call is blocked in Web because of open DB connections
The call to await box.deleteFromDisk(); blocks endlessly on the web due to an open DB connection. The iOS platform does not have this problem.
Hive uses IndexedDB as implementation for the Web-Plattform. The problem lies in line 212 of the file storage_backend_js.dart. Here deleteDatabase is called and awaited.
// directly deleting the entire DB if a non-collection Box
if (_db.objectStoreNames?.length == 1) {
await indexDB!.deleteDatabase(_db.name!);
} else {
If you look at the w3c standard documentation of the deleteDatabase method, you will see that the call blocks on open database connections until all database connections are closed. A version change event is fired for this.
The Dart implementation of the deleteDatabase method shows the possibility to register an onBlocked event listener.
If this is done, an IDBVersionChangeEvent appears in the log, confirming the assumption.
await (indexDB! as IdbFactory).deleteDatabase(_db.name!, onBlocked: (event) { print(event);});
For Web, the problem can be solved by calling the method close beforehand. In the mobile environment however then the following error occurs.
FileSystemException: File closed, path = '/data/user/0/de.hschaeufler.app/app_flutter/cache_box.hive'
This is a deviation between the web and mobile implementation of Hive. Considering the IndexedDB standard, open database connections during deletion, should be taken into account possibly directly when creating the database connection.
w3c IndexedDB upgradeneeded Event
An event with type versionchange will be fired at an open connection if an attempt is made to upgrade or delete the database. This gives the connection the opportunity to close to allow the upgrade or delete to proceed.
w3c Handling Versionchange - Example 2
Another way is to call the connection's close() method. However, you need to make sure your app is aware of this, as subsequent attempts to access the database will fail.
db.onversionchange = function() { saveUnsavedData().then(function() { db.close(); stopUsingTheDatabase(); }); };
function stopUsingTheDatabase() { // Put the app into a state where it no longer uses the database. }
Version
- Platform: Web, iOS
- Flutter version: 3.7.5
- Hive version: 2.2.3
any updates?