Skip to main content

Persisting Queries

Implementing offline capabilites by your own can be hard to do (and maintain!!) so Fl-Query makes easier for developers to do it. Fl-Query uses Hive to persist queries to disk. Hive is a Open Source, "lightweight and buzzing-fast key-value database made for Flutter and Dart."

We're using hive because it supports storing unstructured data and the write speed is blazingly fast

But it is planned to support multiple types of Database for persisting using an Adapter pattern

Persisting Queries

Queries can be persisted by passing jsonConfig argument to the QueryBuilder or useQuery. Persisted queries are stored in hive cache and are available even after the app is restarted

First make sure your custom data type is json serializable. You can use json_serializable package to generate toJson and fromJson methods for your data type

import 'package:json_annotation/json_annotation.dart';

part 'todo.g.dart';

()
class Todo{
final String id;
final String title;
final bool completed;

Todo({
required this.id,
required this.title,
required this.completed,
});

factory Todo.fromJson(Map<String, dynamic> json) => _$TodoFromJson(json);
Map<String, dynamic> toJson() => _$TodoToJson(this);
}
QueryBuilder<Todo, HttpException>(
"todos",
() => api.getTodos(),
jsonConfig: JsonConfig(
fromJson: (json) => Todo.fromJson(json),
toJson: (todo) => todo.toJson(),
),
builder: (context, query) {
/* ... */
},
);

Right now due to lack of reflection support and compile time macros we're unable to serialize any data type on the fly. That's why JsonConfig is required. Otherwise, a simple persistToDisk: true would have been enough

Persisting InfiniteQueries

Just like Query, InfiniteQuery also accepts jsonConfig argument to persist page data to disk. With persisting InfiniteQuery you can achieve similar results like facebook/twitter's offline mode

InfiniteQueryBuilder<PagedPosts, ClientException, int>(
"posts",
(page) => api.getPostsPaginated(page),
nextPage: (lastPage, lastPageData) {
/// returning [null] will set [hasNextPage] to [false]
if (lastPageData.posts.length < 10) return null;
return lastPage + 1;
},
initialPage: 0,
jsonConfig: JsonConfig(
fromJson: (json)=> PagedPosts.fromJson(json),
toJson: (pagedPosts) => pagedPosts.toJson(),
),
builder: /*...*/
);

This will persist each available page to a HiveStore