I'm writing a simple Flutter app with Moor; I have created the table, database and dao, but when I launch the app it crashes with an error that the libsqlite3.so
library can't be found.
This is my database
import 'dart:async';
import 'package:moor_ffi/moor_ffi.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as p;
import 'package:moor/moor.dart';
import 'dart:io';
part 'word_database.g.dart';
class Words extends Table {
IntColumn get id => integer().autoIncrement()();
TextColumn get english => text()();
TextColumn get korean => text()();
}
LazyDatabase _openConnection() {
return LazyDatabase(() async {
final dbFolder = await getApplicationDocumentsDirectory();
final file = File(p.join(dbFolder.path, 'db.sqlite'));
return VmDatabase(file);
});
}
@UseMoor(tables: [Words], daos: [WordDao])
class WordDatabase extends _$WordDatabase {
WordDatabase() : super(_openConnection());
@override
int get schemaVersion => 1;
}
@UseDao(tables: [Words])
class WordDao extends DatabaseAccessor<WordDatabase> with _$WordDaoMixin {
final WordDatabase db;
WordDao(this.db) : super(db);
Future<List<Word>> getAllWords() => select(words).get();
Future<List<Word>> getWordById(int id) => (select(words)
..limit(1)
..where((word) => word.id.equals(id)))
.get();
Stream<List<Word>> watchAllWords() => select(words).watch();
Future<int> insertWord(Word word) => into(words).insert(word);
Future updateWord(Word word) => update(words).replace(word);
Future deleteWord(Word word) => delete(words).delete(word);
}
and this is my error
E/flutter (14384): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: Invalid argument(s): Failed to load dynamic library (dlopen failed: library "/data/data/com.test.sample/lib/libsqlite3.so" not found)
E/flutter (14384): #0 _open (dart:ffi-patch/ffi_dynamic_library_patch.dart:13:55)
E/flutter (14384): #1 new DynamicLibrary.open (dart:ffi-patch/ffi_dynamic_library_patch.dart:22:12)
E/flutter (14384): #2 _defaultOpen (package:moor_ffi/src/load_library.dart:41:31)
E/flutter (14384): #3 OpenDynamicLibrary.openSqlite (package:moor_ffi/src/load_library.dart:99:12)
E/flutter (14384): #4 new _SQLiteBindings (package:moor_ffi/src/bindings/bindings.dart:121:19)
E/flutter (14384): #5 bindings (package:moor_ffi/src/bindings/bindings.dart:262:53)
E/flutter (14384): #6 new Database.open (package:moor_ffi/src/impl/database.dart:52:9)
E/flutter (14384): #7 new Database.openFile (package:moor_ffi/src/impl/database.dart:37:52)
E/flutter (14384): #8 _VmDelegate.open (package:moor_ffi/src/vm_database.dart:39:22)
E/flutter (14384): #9 DelegatedDatabase.ensureOpen.<anonymous closure> (package:moor/src/runtime/executor/helpers/engines.dart:244:22)
E/flutter (14384): <asynchronous suspension>
E/flutter (14384): #10 DelegatedDatabase.ensureOpen.<anonymous closure> (package:moor/src/runtime/executor/helpers/engines.dart)
E/flutter (14384): #11 BasicLock.synchronized (package:synchronized/src/basic_lock.dart:32:26)
E/flutter (14384): #12 DelegatedDatabase.ensureOpen (package:moor/src/runtime/executor/helpers/engines.dart:238:25)
E/flutter (14384): #13 LazyDatabase.ensureOpen.<anonymous closure> (package:moor/src/utils/lazy_database.dart:43:49)
E/flutter (14384): #14 _rootRunUnary (dart:async/zone.dart:1192:38)
E/flutter (14384): #15 _CustomZone.runUnary (dart:async/zone.dart:1085:19)
E/flutter (14384): #16 _FutureListener.handleValue (dart:async/future_impl.dart:141:18)
E/flutter (14384): #17 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:682:45)
E/flutter (14384): #18 Future._propagateToListeners (dart:async/future_impl.dart:711:32)
E/flutter (14384): #19 Future._completeWithValue (dart:async/future_impl.dart:526:5)
E/flutter (14384): #20 Future._asyncComplete.<anonymous closure> (dart:async/future_impl.dart:556:7)
E/flutter (14384): #21 _rootRun (dart:async/zone.dart:1184:13)
E/flutter (14384): #22 _CustomZone.run (dart:async/zone.dart:1077:19)
E/flutter (14384): #23 _CustomZone.runGuarded (dart:async/zone.dart:979:7)
E/flutter (14384): #24 _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1019:23)
E/flutter (14384): #25 _microtaskLoop (dart:async/schedule_microtask.dart:43:21)
E/flutter (14384): #26 _startMicrotaskLoop (dart:async/schedule_microtask.dart:52:5)
E/flutter (14384):
Thanks for any help.
Moor is a library allowing us to work with Flutter’s SQLite database fluently and in pure Dart. Moor also uses SQLite package. In flutter, it becomes very easy to create a database without writing code for SQL tables. Moor itself uses SQL as its backend so in flutter we can directly create a Table using Dart. Why Moor? Why Moor?
M oor is just a Room spelled backward. Moor is a library allowing us to work with Flutter’s SQLite database fluently and in pure Dart. Moor also uses SQLite package. In flutter, it becomes very easy to create a database without writing code for SQL tables. Moor itself uses SQL as its backend so in flutter we can directly create a Table using Dart.
But, Flutter’s “libflutter.so” was only present under “armeabi-v7a” folder. Little more RnD and from stackoverflow answer I came to know:
There is another alternative for the web: https://github.com/sql-js/sql.js. The fact is it's very difficult allow sqlite be abstracted to local storage in browser. But at least Moor is trying to achieve it. For those that are looking to DateTime converters both Floor and Moor already support it.
after long research, my issue was resolved by adding
sqlite3_flutter_libs
in pubspec.yaml
After some research it appears this is a regression in Flutter. To address we need to update settings.gradle
.
Below are the original (commented out) and updated versions:
/*
include ':app'
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
assert localPropertiesFile.exists()
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
*/
include ':app'
def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
def plugins = new Properties()
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
if (pluginsFile.exists()) {
pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
}
plugins.each { name, path ->
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
include ":$name"
project(":$name").projectDir = pluginDirectory
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With