deleteFromDisk-Call is blocked in Web because of open DB connections
- Dominant language
- Dart
- Stars
- 4.4k
- Forks
- 449
- PR merge metrics
- No merged PRs in 30d
Description
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](https://w3c.github.io/IndexedDB/#dom-idbopendbrequest-onblocked) 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 ](https://api.dart.dev/stable/2.19.6/dart-indexed_db/IdbFactory/deleteDatabase.html) 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](https://w3c.github.io/IndexedDB/#eventdef-idbopendbrequest-upgradeneeded )
> 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](https://w3c.github.io/IndexedDB/#handling-versionchange)
> 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
Contributor guide
No contributing guide indexed for this repository
Research direction
Start in storage_backend_js.dart around line 212, where deleteFromDisk awaits deleteDatabase, and review the web database connection lifecycle. Compare the proposed close behavior with the mobile implementation and verify that deleteFromDisk completes on the web without causing the reported mobile FileSystemException.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- dart, flutter
- Domain
- database
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100