simolus3 / drift

Drift is an easy to use, reactive, typesafe persistence library for Dart & Flutter.
https://drift.simonbinder.eu/
MIT License
2.55k stars 364 forks source link

Encryption Example - libsqlite3.so not found #2973

Closed andyyapwl closed 4 months ago

andyyapwl commented 4 months ago

hi, i tried to flutter run the examples/encryption in my android emulator but got the below error:

I/flutter (13408): Error loading data: Invalid argument(s): Failed to load dynamic library '/data/data/com.example.drift_encryption_sample/lib/libsqlite3.so': dlopen failed: library "/data/data/com.example.drift_encryption_sample/lib/libsqlite3.so" not found

below is my pubspec.yaml: dependencies: sqflite: ^2.3.0 drift_sqflite: ^2.0.1 drift: ^2.0.2+1 sqlcipher_flutter_libs: ^0.6.0 flutter: sdk: flutter path_provider: ^2.0.11 path: ^1.8.1 sqlite3: '>=1.8.0 <3.0.0'

I noticed the package sqlcipher_flutter_libs will not generate libsqlite3.so into the build folder..

simolus3 commented 4 months ago

Thanks for the report! In that example, we're using this to override how we open sqlcipher: https://github.com/simolus3/drift/blob/9c28a060206ffb991e30009a8e4fb9137d572051/examples/encryption/lib/main.dart#L11-L16

Problematically, we're also using NativeDatabase.createInBackground, which uses a background isolate to manage the database connection. As isolates don't share global variables, the behavior didn't get applied. I've fixed this in a1af6f6114960caaee6a9d7699e27f92cc8c93dc, the solution is to move the setup code into isolateSetup.

andyyapwl commented 4 months ago

Thank you for your prompt response! The 'libsqlite3.so' error has been resolved, but I encountered a new error on the Android emulator:

SqliteException(26): while executing, file is not a database, file is not a database (code 26) Causing statement: select count(*) from sqlite_master,

My cipher_version is 4.5.7 community.

Upon investigation, I discovered that changing the database name from 'File(p.join(path.path, 'app.db.enc'))' to 'File(p.join(path.path, 'app.db.sqlite'))' resolves the issue. It appears that the database file was previously created but not encrypted due to the 'libsqlite3.so not found' error. After updating the isolateSetup code, it attempted to encrypt the existing database file, leading to the 'file is not a database' error. This error occurs because we can only encrypt a new database file, not an existing one.

I extracted the 'app.db.sqlite' file from the Android emulator and opened it with SQLiteStudio successfully. I was able to open the database file using the SQLCipher type with a password.

I was stuck on this issue for three days, but your revised code and explanation saved my day!