simolus3 / drift

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

Error if use sqlcipher_flutter_libs #3226

Open andim27 opened 2 months ago

andim27 commented 2 months ago

Android, mobile drift: ^2.20.2 drift_flutter: ^0.1.0 sqlite3: ^2.4.6 sqlcipher_flutter_libs: ^0.6.4

NativeDatabase.createInBackground(
      file,
      isolateSetup: () async {
        if (Platform.isAndroid) {
          setupSqlCipher();//code from docs
        }
      },
      setup: (rawDb) {
        final result = rawDb.select('pragma cipher_version');
        if (result.isEmpty) {
           throw UnsupportedError(
             'This database needs to run with SQLCipher, but that library is '
             'not available!',
           );

        }
        final escapedKey = _encryptionPassword.replaceAll("'", "''");
        rawDb.execute("PRAGMA key = '$escapedKey';");
        rawDb.config.doubleQuotedStringLiterals = false;
        final firstRes = rawDb.select('select count(*) from sqlite_master');
        //---Error:
       //.    SqliteException(26): while preparing statement, file is not a database, file is not a database (code 26)
        //.   I/flutter ( 5781):   Causing statement: select count(*) from sqlite_master
      },
    );
  });

Please answer because the documentation is not clear. Do I need encrypted db-file before using(and call) sqlcipher_flutter_libs ?

simolus3 commented 2 months ago

Unfortunately you can't reliably use drift_flutter and sqlcipher_flutter_libs in the same app, as drift_flutter depends on sqlite3_flutter_libs (Android might be the only platform where that doesn't immediately fail the build, you'll run into issues on other platforms for sure). There's a manual setup dropdown here which you can use as a reference for avoiding drift_flutter in this case.

Considering that pragma cipher_version works, the library should be set up correctly. So you're either using the wrong key (or you're using an existing unencrypted database, if that was your question?)

Do I need encrypted db-file before using(and call) sqlcipher_flutter_libs ?

You can't encrypt a previously unencrypted database with PRAGMA key alone, you'd have to do this. Depending on your setup, you could make sure the existing database (if it's e.g. loaded from assets) is effectively unencrypted by using a static hardcoded key, and then use pragma rekey to encrypt the database with a secure key.