Hive - fast local base for Flutter, Dart

About a month ago, talking with one application developer on Flutter, there was a problem of braking the processing of small (in tens of thousands) data arrays on the user's phone.


Many applications require data processing on the phone and, further, their synchronization with the backend. For example: to-do lists, lists of any data (analyzes, notes, etc.).


It’s not at all cool when the list of just a few thousand items, when you delete one of them and then write to the cache or when searching the cache, starts to slow down.


There is a solution! Hive - noSql base written in pure Dart, very fast. In addition, the advantages of Hive:


  • Cross-platform - since there are no native dependencies on pure Dart - mobile, desktop, browser.
  • High performance.
  • Built-in strong encryption.

In the article, we will see how to use Hive and make a simple ToDo application, which in the next article will be supplemented by authorization and synchronization with the cloud.



 


Start


Here we will write such an application at the end of the article, the code is posted on github .



One of the advantages of Hive is the very good documentation https://docs.hivedb.dev/ - in theory everything is there. In the article, I will simply briefly describe how to work with what and make an example.


So, to connect hive to the project, add to pubspec.yaml


dependencies:
  hive: ^1.4.1+1
  hive_flutter: ^0.3.0+2

dev_dependencies:
  hive_generator: ^0.7.0+2
  build_runner: ^1.8.1

Next, initialize, usually at the beginning of the application.


await Hive.initFlutter();


, , . hive_flutter: ^0.3.0+2 β€” Flutter.



, Hive List, Map, DateTime, BigInt Uint8List.


, TypeAdapters. https://docs.hivedb.dev/#/custom-objects/type_adapters ( hive_generator: ^0.7.0+2).



class Todo {
  bool complete;
  String id;
  String note;
  String task;
}

id β€” typeId: 0


import 'package:hive/hive.dart';
part 'todo.g.dart';
@HiveType(typeId: 0)
class Todo {
  @HiveField(0)
  bool complete;
@HiveField(1)
  String id;
@HiveField(2)
  String note;
@HiveField(3)
  String task;
}

, , . Hive.



flutter packages pub run build_runner build --delete-conflicting-outputs
todo.g.dart


\ Hive.


HiveObject β€” Todo HiveObject


class Todo extends HiveObject {


2 save() delete(), .


β€” Box


hive (box). , , ..


Box . , ( ).
var todoBox = await Hive.openBox<Todo>('box_for_todo');
read / write .


, :


,
var stringBox = await Hive.openBox<String>('name_of_the_box');



stringBox.put('key1', 'value1');
print(stringBox.get('key1')); // value1
stringBox.put('key2', 'value2');
print(stringBox.get('key2')); // value2

+


List. autoinrement.


: getAt(), putAt() and deleteAt()


add() .


stringBox.put('value1');
stringBox.put('value2');
stringBox.put('value3');
print(stringBox.getAt(1)); //value2

? , Hive. Listeners , . ( , ), Listeners . await .

,
var stringBox = await Hive.box<String>('name_of_the_box');
, singleton.


, , , ,
var stringBox = await Hive.openBox<String>('name_of_the_box');


  • , .

, :


  /// Returns a previously opened box.
  Box<E> box<E>(String name);
  /// Returns a previously opened lazy box.
  LazyBox<E> lazyBox<E>(String name);
  /// Checks if a specific box is currently open.
  bool isBoxOpen(String name);
  /// Closes all open boxes.
  Future<void> close();

Devhack , Flutter β€” open source, , , .

LazyBox β€”


, . . , - .


, lazily


var lazyBox = await Hive.openLazyBox('myLazyBox');
var value = await lazyBox.get('lazyVal');

Hive . , Hive .



Hive AES-256 .
256-
var key = Hive.generateSecureKey();
Fortuna random number generator.



var encryptedBox = await Hive.openBox('vaultBox', encryptionKey: key);
encryptedBox.put('secret', 'Hive is cool');
print(encryptedBox.get('secret'));

:


  • , plaintext.
  • flutter_secure_storage .
  • , , .


, , .


,


var box = Hive.box('myBox');
await box.compact();
await box.close();

todo_hive_example


, , , .
, .


:


  • β€” +

:


  • +
  • β€” \
  • β€”

1 β€”


, , ( +.


, .
.


(, Dart (extensions)), /hive_flutter-0.3.0+2/lib/src/box_extensions.dart


/// Flutter extensions for boxes.
extension BoxX<T> on Box<T> {
  /// Returns a [ValueListenable] which notifies its listeners when an entry
  /// in the box changes.
  ///
  /// If [keys] filter is provided, only changes to entries with the
  /// specified keys notify the listeners.
  ValueListenable<Box<T>> listenable({List<dynamic> keys}) =>
      _BoxListenable(this, keys?.toSet());
}

, .

, ,


      body: ValueListenableBuilder(
        valueListenable: Hive.box<Todo>(HiveBoxes.todo).listenable(),
        builder: (context, Box<Todo> box, _) {
          if (box.values.isEmpty)
            return Center(
              child: Text("Todo list is empty"),
            );
          return ListView.builder(
            itemCount: box.values.length,
            itemBuilder: (context, index) {
              Todo res = box.getAt(index);
              return ListTile(
                title: Text(res.task),
                subtitle: Text(res.note),
              );
            },
          );
        },
      ),

. + .


, +.


Add , .


void _onFormSubmit() {
    Box<Todo> contactsBox = Hive.box<Todo>(HiveBoxes.todo);
    contactsBox.add(Todo(task: task, note: note));
    Navigator.of(context).pop();
  }

, , Todo. Hive.


github .


2 β€” \


. , class Todo extends HiveObject



                  leading: res.complete
                      ? Icon(Icons.check_box)
                      : Icon(Icons.check_box_outline_blank),
                  onTap: () {
                    res.complete = !res.complete;
                    res.save();
                  });

github .


3 β€” β€”


. dismissable .


                background: Container(color: Colors.red),
                key: Key(res.id),
                onDismissed: (direction) {
                  res.delete();
                },

, , .


github β€” https://github.com/awaik/todo_hive_example


To be continued:


  • BLoC. , , Apple Id.
  • Firebase GraphQl . ( ).

All Articles