No SQL Persistence Database in Flutter
Over the previous couple of years we've seen the increase of a replacement sort of databases, referred to as NoSQL databases, that are challenging the dominance of relational databases. Relational databases have dominated the software industry for an extended time providing mechanisms to store data persistently, concurrency control, transactions, mostly standard interfaces and mechanisms to integrate application data, reporting. The dominance of relational databases, however, is cracking.
What is NoSQL Persistence Database and how do you categorise these databases?
NoSQL databases ("not only SQL") are non tabular, and store data differently than relational tables. NoSQL databases come in a variety of types based on their data model. The main types are document, key-value, wide-column, and graph. In a simple we can define the NoSQL as below points:
- Not using the relational model
- Running well on clusters
- Mostly open-source
- Schema-less
Why NoSQL Database?
NoSQL is built to support exactly such fast moving requirements whereas a relational database is inherently slow to such changes due to its rigid data structure. NoSQL databases fully support agile development.
No SQL Database in Flutter
1) Firebase - online NoSQL storage
Firebase from Google provides its NoSQL database for Flutter applications where the JSON protocol can be used for doing all the data retrieval and storage operations. This is one of Flutter Applications’ best options because of its data synchronisation feature and fast loading times.
Features
- NoSQL database
- REST APIs
- Analytics
- Authentication
- Storage
Pros 👍
- Synchronises with Firebase online in a near real-time fashion.
- Great tooling support.
- Easy to browse data online via the Firebase Console.
Cons 👎
- Firebase setup can be complicated if you don’t already have it added to your app.
- As the database is online, you need to be mindful of a lot more than a strictly on-device database (like access permissions, for instance).
- Firebase support for Flutter isn’t in a production ready state just yet.
2) Hive - offline NoSQL storage
Hive is an extremely fast NoSQL storage option for Flutter developers. Its biggest selling point is that it is completely native to Dart. This means that anywhere Dart goes, Hive can go, as it doesn’t require any device-specific implementations.
Features
- Cross platform: mobile, desktop, browser
- Simple, powerful, & intuitive API
- Strong encryption built in
- NO native dependencies
- Batteries included
Add to project
Add the following to your pubspec.yaml
:
dependencies:
hive: ^1.4.4+1
hive_flutter: ^0.3.1
dev_dependencies:
hive_generator: ^0.8.2
build_runner: ^1.10.12
Initialize
Initializes Hive with a valid directory in your app files. You can also provide a subdirectory:
await Hive.initFlutter();
Use Hive.init()
for non-Flutter apps.
Open a Box
All of your data is stored in boxes.
You may call box('testBox')
to get the singleton instance of an already opened box.
Read & Write
Hive supports all primitive types, List
, Map
, Date Time
, BigInt
and Uint8List
. Any object can be can stored using Type Adapters.
Store objects
Hive not only supports primitives, lists and maps but also any Dart object you like. You need to generate a type adapter before you can store objects.
Extending HiveObject
is optional but it provides handy methods like save()
and delete()
.
var box = await Hive.openBox('myBox');
var person = Person()
..name = 'Dave'
..age = 22;
box.add(person);
print(box.getAt(0)); // Dave - 22
person.age = 30;
person.save();
print(box.getAt(0)) // Dave - 30
Hive For️ Flutter
Hive was written with Flutter in mind. It is a perfect fit if you need a lightweight datastore for your app. After adding the required dependencies and initializing Hive, you can use Hive in your project:
import 'package:hive/hive.dart';
import 'package:hive_flutter/hive_flutter.dart';
class SettingsPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ValueListenableBuilder(
valueListenable: Hive.box('settings').listenable(),
builder: (context, box, widget) {
return Switch(
value: box.get('darkMode'),
onChanged: (val) {
box.put('darkMode', val);
}
);
},
);
}
}
Boxes are cached and therefore fast enough to be used directly in the build()
method of Flutter widgets.
3) Sembast Database
sembast db stands for Simple Embedded Application Store database
Add this to your package's pubspec.yaml file:
dependencies:
sembast: ^2.4.8+1
Opening a database
A database is a single file represented by a path in the file system.
The db object is ready for use.
Store Database
On flutter you need to find a proper location for the database. One solution is to use the path_provider
package get a directory in which you want to create the database.
Flutter Web
On flutter web, sembast_web
should be used.
Database migration
Like in some other databases (sqflite, indexed_db), the database has a version that the app can use to perform migrations between application releases. When specifying a version
during openDatabase
, the callback onVersionChanged
is called if the version differs from the existing.
Practically the version is a constant for an application version and is used to eventually change some data to match the new expected format.
See complete migration example here.
Preloading data
The basic versioning system can also be used to preload data. Data must be inserted record by record, coming from another database (or asset in flutter) or from a custom format.
So many options! Which one should I use?
- If you need your data synchronized between devices and you don’t mind the fairly extended setup, you should use Firebase.
- If you want to be up and running really quickly and want great support for the web plus anything else Dart runs on, you should use Hive. If you want something that works anywhere, Hive is for you.
If I was making an app today, I would probably use Hive.