Historical archive
Persisting Flutter App State with sqflite
A small Flutter example that wraps sqflite database operations and uses a stored launch counter to choose between welcome and waiting screens.
Flutter apps commonly use one of two approaches for local persistence:
shared_preferencesstores simple key-value data in a local file and feels similar to browserlocalStorage.sqfliteprovides a complete local SQLite database.
Database wrapper
The following class wraps basic database initialization, querying, and updating:
import 'package:sqflite/sqflite.dart';
class SqlLite {
final sqlFileName = "bonfire.sql";
final userState = "userState";
Database db;
open() async {
String path = "${await getDatabasesPath()}/$sqlFileName";
if (db == null) {
db = await openDatabase(path, version: 1, onCreate: (db, ver) async {
await db.execute("""
Create Table userState(
welComeTimes int,
code int
);
""");
await db.insert("userState", {'welComeTimes': 0, 'code': 200});
});
}
}
queryUserState() async {
return await db.query(userState, columns: null);
}
insertUserState(Map<String, dynamic> m) async {
return await db.update(userState, m);
}
}
Use the stored state
This example opens a welcome or onboarding page the first time the app launches, then opens the normal waiting page on later launches:
import 'package:flutter_module/database/sqflite.dart';
final _sqlite = SqlLite();
await _sqlite.open();
print(await _sqlite.queryUserState());
List<Map<String, dynamic>> result = await _sqlite.queryUserState();
if (result[0]['code'] == 200) {
if (result[0]['welComeTimes'] == 0) {
_sqlite.insertUserState({
"welComeTimes": result[0]['welComeTimes'] + 1
});
return Navigator.of(context).push(
SlideInFromBottomRoute(Welcome())
);
} else {
return Navigator.of(context).push(
SlideInFromBottomRoute(Waiting())
);
}
}
The sample reflects an older null-safety era of Dart. Modern code should add explicit types, lifecycle handling, migrations, and database error handling.