This is an example of how to use RxDB as a database inside of a Flutter application. It is able to insert documents and run and observe queries to create a reactive application that always renders the current database state.
IMPORTANT: This is highly experimental, it works but many parts are missing. If you need any missing functionality, you are expected to make a pull request.
RxDB is written in TypeScript and compiled to JavaScript. To run it in a Flutter application, the flutter_qjs library is used to spawn a QuickJS JavaScript runtime. RxDB itself runs in that runtime and communicates with the flutter dart runtime. To store data persistent, the LokiJS RxStorage is used together with a custom storage adapter that persists the database inside of the shared_preferences data.
To use RxDB, you have to create a compatible JavaScript file that creates your RxDatabase
and starts some connectors which are used by Flutter to communicate with the JavaScript RxDB database via setFlutterRxDatabaseConnector()
.
Use the index.js as a reference.
import {
createRxDatabase
} from 'rxdb';
import {
getRxStorageLoki
} from 'rxdb/plugins/storage-lokijs';
import {
setFlutterRxDatabaseConnector,
getLokijsAdapterFlutter
} from 'rxdb/plugins/flutter';
// do all database creation stuff in this method.
async function createDB(databaseName) {
// create the RxDatabase
const db = await createRxDatabase({
// the database.name is variable so we can change it on the flutter side
name: databaseName,
storage: getRxStorageLoki({
adapter: getLokijsAdapterFlutter()
}),
multiInstance: false
});
await db.addCollections({
heroes: {
schema: {
version: 0,
primaryKey: 'id',
type: 'object',
properties: {
id: {
type: 'string',
maxLength: 100
},
name: {
type: 'string',
maxLength: 100
},
color: {
type: 'string',
maxLength: 30
}
},
indexes: ['name'],
required: ['id', 'name', 'color']
}
}
});
return db;
}
// start the connector so that flutter can communicate with the JavaScript process
setFlutterRxDatabaseConnector(
createDB
);
Before you can use the JavaScript code, you have to bundle it into a single .js
file. In this example we do that with webpack
in a npm script here which bundles everything into the javascript/dist/index.js
file.
To allow Flutter to access that file during runtime, add it to the assets
inside of your pubspec.yaml:
flutter:
assets:
- javascript/dist/index.js
First you have to use the rxdb dart package as a flutter dependency. Currently the package is not published at the dart pub.dev. Instead you have to install it from the local filesystem inside of your RxDB npm installation.
# inside of pubspec.yaml
dependencies:
rxdb:
path: path/to/your/node_modules/rxdb/src/plugins/flutter/dart
Afterwards you can import the rxdb library in your dart code and connect to the JavaScript process from there. For reference, check out the lib/main.dart file.
import 'package:rxdb/rxdb.dart';
// start the javascript process and connect to the database
RxDatabase myDatabase = await getRxDatabase("javascript/dist/index.js", databaseName);
// get a collection
RxCollection myCollection = database.getCollection('heroes');
// insert a document
RxDocument myDocument = await collection.insert({
"id": "zflutter-${DateTime.now()}",
"name": nameController.text,
"color": colorController.text
});
// create a query
RxQuery<RxHeroDocType> myQuery = RxDatabaseState.collection.find();
// subscribe to a query
myQuery.$().listen((newResults) {
setState(() {
documents = newResults;
});
});
- First you have to bundle the JavaScript by running
npm run install && npm run build
in the /javascript directory. You have to rerun this command each time you change the JavaScript code. - In your terminal, execute
flutter run
to start the example application.