hive
hive copied to clipboard
Flutter: Hive files exposed to user on (theoricaly all) platforms and potentially common between different apps
Steps to Reproduce
Do Hive.initFlutter()
Code sample
Hive.initFlutter() is using getApplicationDocumentsDirectory which is designed to provide a folder accessible to users and therefor also "common between different apps" (source: "path_provider" package) !
(go to More info section to see the folders depending on the platform)
Version
- Platform: Mac, Windows, Linux, (iOS and Android theoricaly but not in practice even though it seems to impact some people: https://github.com/hivedb/hive/issues/840)
- Flutter version: [3.0.5]
- Hive version: [all, including 2.2.3]
How to fix
Use getApplicationSupportDirectory instead of getApplicationDocumentsDirectory or at least allow to use completly other folder at https://github.com/hivedb/hive/blob/3b12c31a221f97f5ec86fe20df63515aeedf88f0/hive_flutter/lib/src/hive_extensions.dart#L16
Other solution: Add a comment to explain the implication of initFlutter without using getApplicationSupportDirectory (but with this solution, most users will use the "default bad choice"... Because most users should do :
import 'package:flutter/foundation.dart' show kIsWeb;
if (kIsWeb) {
await Hive.initFlutter();
} else {
await Hive.initFlutter((await getApplicationSupportDirectory()).path);
}
and not await Hive.initFlutter(); but is really dirty as it implies we need to rely on path.join(badDir, goodDir) to understand what we mean... (this function is not intended this way...) https://github.com/hivedb/hive/blob/3b12c31a221f97f5ec86fe20df63515aeedf88f0/hive_flutter/lib/src/hive_extensions.dart#L17
Ressources
path_provider documentation:
/// Use this for files you donβt want exposed to the user. Your app should not
/// use this directory for user data files.
/// (...)
getApplicationSupportDirectory
/// Path to a directory where the application may place data that is
/// user-generated, or that cannot otherwise be recreated by your application.
/// On iOS, this uses the `NSDocumentDirectory` API. Consider using
/// [getApplicationSupportDirectory] instead if the data is not user-generated.
/// (...)
getApplicationDocumentsDirectory
More Info
Here are where data are stored depending on the function called:
getApplicationDocumentsDirectory:
- Windows:
C/Users/{username}/Documents/(User accessible AND files common between apps ππ ) - Linux:
/home/{user}/(User accessible AND files common between apps ππ ) - Android :
/data/user/0/{YourAppName}/app_flutter/(Not really accessible so I guess it is "ok" & dependent on app π) - MacOS (Not tested, but I guess, it is like Linux & Windows ππ )
- IOS (Not tested, but from documentation, it is specified we should NOT use this function... π )
- Web: Not using this function (π )
getApplicationSupportDirectory :
- Windows:
C:\Users\{user}\AppData\Roaming\{YourAppOrganization}\{YourAppName}/(Not accessible & dependent on app π ) - Linux:
/home/{user}/.local/share/{YourAppName]/(Not accessible & dependent on app π ) - Android:
/data/user/0/{YourAppName}/files/(Not accessible & dependent on app π) - MacOS (Not tested, but I guess, it is like Linux & Windows π )
- IOS (Not tested, but from documentation, it is specified we SHOULD use this function... π )
- Web: Not using this function (π )
Agreed. There's been some ongoing discussion on it for some time now: https://github.com/hivedb/hive/pull/746.
There's a comment in there that you can apparently use Hive.init and pass it whatever directory you'd like since initFlutter effectively calls init anyway. e.g.:
final suppDir = await getApplicationSupportDirectory();
Hive.init(suppDir.path);
I've never used Hive before so hopefully it works well; migration would be another case.
In Flutter I cloud set the path so it was not visible in Files
String? path = (await getApplicationSupportDirectory()).path;
await Hive.initFlutter();
await Hive.openBox(boxApp, path: path);
await Hive.openBox(boxUser, path: path);