Hive database in Flutter - An overview

Mustafa Tahir
4 min readJun 9, 2022

--

Hey folks out there,

Introduction

Hive database was designed with Flutter, a concept of Light-weight, blazingly fast, Local, NoSQL approach for developers written purely in Dart Programming language.

Advantages

Supports all platforms

No native dependencies required

Fast, light-weight, and efficient

Example Project: Book CRUD

Approach

Hive Box

Hive uses Box, an organized technique to store all the data. You can compare a Hive box with SQL table, but it does not have any structure and can contain anything.

Type Adapters

Type Adapter here acts as a convertor of Object to and from a binary form, since Hive uses primitive types such as List, Map, DateTime and Uint8List respectively.

Type Adapter needs to be generated, you can write yourself but the safest way is to generate them. Use hive_generator for that.

Since, we are using Book CRUD, we only have three fields,

id

book_title

book_author

Now, moving to the implementation part.

Adding packages

https://pub.dev/packages/hive

Before using Hive, we need to add some packages in “pubspec.yaml

Add these in dependencies

hive: any
hive_flutter: any

Add these in dev_dependencies

hive_generator: any
build_runner: any

Now, initialize with this command under main() function

await Hive.initFlutter();

Next, open a Hive box

await Hive.openBox(‘booksbox’);

Now, add another file named “books.dart” and add this snippet

import 'package:hive/hive.dart';

part 'books.g.dart';

@HiveType(typeId: 1)
class Books {
Books({this.id,this.book_title,this.book_author});
@HiveField(0)
int? id;

@HiveField(1)
String? book_title;

@HiveField(2)
String? book_author;
}

You can see in the above snippet, each field annotated with @HiveField has a unique number and used to identify the fields.

Next, under the project terminal

Add this line flutter packages pub run build_runner build

It will generate TypeAdapters for books.

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'books.dart';

// **************************************************************************
// TypeAdapterGenerator
// **************************************************************************

class BooksAdapter extends TypeAdapter<Books> {
@override
final int typeId = 1;

@override
Books read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return Books()
..id = fields[0] as int
..book_title = fields[1] as String
..book_author = fields[2] as String;
}

@override
void write(BinaryWriter writer, Books obj) {
writer
..writeByte(3)
..writeByte(0)
..write(obj.id)
..writeByte(1)
..write(obj.book_title)
..writeByte(2)
..write(obj.book_author);
}

@override
int get hashCode => typeId.hashCode;

@override
bool operator ==(Object other) =>
identical(this, other) ||
other is BooksAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}

In addition, now place this adapter in your main() method as

Hive.registerAdapter(BooksAdapter());

After adding, your main() function will look like this

Here, we conclude our database part.

User Interface(UI) Part

Create a new dart file as “my_books.dart” and add this snippet

import 'package:flutter/material.dart';
import 'package:hive_demo/Model/books.dart';
import 'package:hive_demo/main.dart';
import 'package:hive_flutter/adapters.dart';

class MyBooks extends StatefulWidget {
const MyBooks({Key? key}) : super(key: key);

@override
State<MyBooks> createState() => _MyBooksState();
}

class _MyBooksState extends State<MyBooks> {
final _title = TextEditingController();
final _author = TextEditingController();

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Hive DB"),
),
body: ValueListenableBuilder(
valueListenable: Hive.box<Books>('booksbox').listenable(),
builder: (context, Box<Books> box, _) {
if (box.values.isEmpty) {
return const Center(child: Text("No Books"));
} else {
return ListView.separated(
itemCount: box.values.length,
itemBuilder: (context, index) {
var result = box.getAt(index);

return Card(
child: ListTile(
title: Text(result!.book_title!),
subtitle: Text(result.book_author!),
trailing: InkWell(
child: const Icon(
Icons.remove_circle,
color: Colors.red,
),
onTap: () {
box.deleteAt(index);
},
),
),
);
},
separatorBuilder: (context, i) {
return const SizedBox(height: 12);
},
);
}
},
),
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.add),
onPressed: () => addNewBook(context),
),
);
}

addNewBook(BuildContext context) {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: const Text("New book"),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextFormField(
controller: _title,
decoration: const InputDecoration(hintText: 'Title'),
),
const SizedBox(
height: 15,
),
TextFormField(
controller: _author,
decoration: const InputDecoration(hintText: 'Author'),
),
const SizedBox(
height: 15,
),
ElevatedButton(
onPressed: () async {
await box!.put(
DateTime.now().toString(),
Books(
book_title: _title.text,
book_author: _author.text,
));

Navigator.pop(context);
},
child: const Text("Add")),
],
),
);
});
}
}

Next, for the “main.dart” file,

import 'package:flutter/material.dart';
import 'package:hive_demo/Model/books.dart';
import 'package:hive_demo/Screens/my_books.dart';
import 'package:hive_flutter/adapters.dart';

Box? box;

void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Hive.initFlutter();
box = await Hive.openBox<Books>("booksbox");
Hive.registerAdapter(BooksAdapter());
runApp(const MyApp());
}

class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
title: "Hive Demo",
home: MyBooks(),
);
}
}

After adding, run the app

Pic #1

Pic #2

Pic #3

So, this sums up the article.

I hope you have had a good time reading this one.

If you feel you have grabbed some bit of it then consider clapping this one.

Stay tuned for more articles.

You can find me on GitHub, YouTube.

--

--