Hive Local Database

Abubakar Saddique
7 min readJan 18, 2024

What is Hive Database ??

Hive is the special type of the database in which the data is stored locally on your device storage .

It is the No SQL data base which mean’s you don’t have to write any type of the Queries inside it .

You can add the dependencies of the hive database in your app from the above given package link .

If you wan’t a detail information about the hive database you must read it from the it’s official documentation .

Now come to the code how it work’s .

i ) Data Model :

First you have to make the data model class of whatever you want’s to store inside it .

In my case i want’s to store the product with some of it’s properties . like product name , product serial number , product image , product price .

You have to make the class and assign it a name of your model class and then extend it from the Hive Object class (which was already a part of the above package you have to only use it ).


class ProductModel extends HiveObject {

}

Now you have to add the Hive Type annotation with all of your model classes .


@HiveType(typeId: 0)
class ProductModel extends HiveObject {
}

Now it’s time to add the properties inside that model class .

In my case i have only four properties .


int productId;


String productName;


double productPrice;


String productImageUrl;

Now after adding the properties inside the model class you have to add the Hive Field annotation with all of the properties and assign the index to all of them inside that annotation .

 @HiveField(0)
int productId;

@HiveField(1)
String productName;

@HiveField(2)
double productPrice;

@HiveField(3)
String productImageUrl;

Now you have to make the constructor of your model class .

 ProductModel(
{required this.productId,
required this.productName,
required this.productPrice,
required this.productImageUrl});

Now that’s all for the model class .



import 'package:hive/hive.dart';

@HiveType(typeId: 0)
class ProductModel extends HiveObject {

@HiveField(0)
int productId;

@HiveField(1)
String productName;

@HiveField(2)
double productPrice;

@HiveField(3)
String productImageUrl;

ProductModel(
{required this.productId,
required this.productName,
required this.productPrice,
required this.productImageUrl});
}

ii ) Adapter Class :

Now you have to make the product adapter class . and extend it with the Type adapter and give the model class as the template type of the type adapter class .

When you extend with the type adapter class then you must have to override it’s three method’s . (read , write , typeId) .

Read :

In the read method you have to return the product model after writing the data inside it .

@override
ProductModel read(BinaryReader reader) {
ProductModel productModel = reader.read(0);
return ProductModel(
productId: productModel.productId,
productName: productModel.productName,
productPrice: productModel.productPrice,
productImageUrl: productModel.productImageUrl);
}

The read method will provide you the Binary reader which help’s you to to bring data back from the binary format on the disk.

Now using the read method of the reader class (in which you have to provide the type id value of your model class ) you can get the data of you model class . Now you have to return the model from the read method .

Type Id :

In the type Id you have to provide the type id of that specific model class .

@override
int get typeId => 0;

Write :

In the write code you have to write the code for writting your data in the database . You have to write the code for all of the properties of that model class .

@override
void write(BinaryWriter writer, ProductModel obj) {
writer.write(obj.productId);
writer.write(obj.productName);
writer.write(obj.productPrice);
writer.write(obj.productImageUrl);
}

The write method of the type adapter class will provide you the binary writer (which is used to encode data to the binary format. ) and the model class object .

Now using write method of the binary writer class you have to add the values of all of the properties of the model class inside it .

Now That’s all for the adapter class .


import 'package:flutter_local_data_bases_pracrtice_f12/hive_local_data_base/model/product_model.dart';
import 'package:hive/hive.dart';

class ProductAdaptor extends TypeAdapter<ProductModel> {
@override
ProductModel read(BinaryReader reader) {
ProductModel productModel = reader.read(0);
return ProductModel(
productId: productModel.productId,
productName: productModel.productName,
productPrice: productModel.productPrice,
productImageUrl: productModel.productImageUrl);
}

@override
int get typeId => 0;

@override
void write(BinaryWriter writer, ProductModel obj) {
writer.write(obj.productId);
writer.write(obj.productName);
writer.write(obj.productPrice);
writer.write(obj.productImageUrl);
}
}

iii ) Database Provider :

Now you have to make the database provider class which help’s us to interact with the database .

import 'package:flutter_local_data_bases_pracrtice_f12/hive_local_data_base/model/product_model.dart';
import 'package:hive_flutter/hive_flutter.dart';

class ProductDataBaseProvider {

}

Now first of all you have to make the singleton of that database provider class .

static ProductDataBaseProvider? _productDataBaseProvider;
ProductDataBaseProvider._internal();

factory ProductDataBaseProvider() {
return _productDataBaseProvider ?? ProductDataBaseProvider._internal();
}

Now you have to make a box name and provide the name of the model class . The data in the hive database is store inside the box .

According to the official documentation

In Hive, data is neatly organized into containers known as boxes. Think of boxes as tables you’d find in SQL, but far more flexible — they don’t stick to a set structure and can contain a variety of data. Boxes can be encrypted to store sensitive data.

I make a getter of the box name because i have to use the box name in all of the crud operations for interacting with hive database . If you don’t make a global box name then you have to give the box name as a string inside the all of the crud operations in the next step’s that might cause the chance of increase in error’s .

String get boxName => "product";

Now here you have to write all code for the crud operation’s .

In all of the crud operation’s you must have to add the below line to interact with the database because the data is store in box and you have to open the box for all of the operations .

Box<ProductModel> productBox = await Hive.openBox(boxName);

Boxes contain all of your data. In the browser, each box has its own IndexedDB database. On all other platforms, each Box is stored in a separate file in the Hive home directory.


Future<bool> insertProduct({required ProductModel product}) async {
Box<ProductModel> productBox = await Hive.openBox(boxName);
int effectedRows = await productBox.add(product);
return effectedRows > 0;
}

Future<List<ProductModel>> fetchProducts() async {
Box<ProductModel> productBox = await Hive.openBox(boxName);
List<ProductModel> products = productBox.values.toList();
return products;
}

Future<void> updateProduct(
{required int index, required ProductModel product}) async {
Box<ProductModel> productBox = await Hive.openBox(boxName);
return productBox.putAt(index, product);
}

Future<void> deleteProduce({required int index}) async {
Box<ProductModel> productBox = await Hive.openBox(boxName);
return productBox.deleteAt(index);
}

That’s all for the database provider class .

import 'package:flutter_local_data_bases_pracrtice_f12/hive_local_data_base/model/product_model.dart';
import 'package:hive_flutter/hive_flutter.dart';

class ProductDataBaseProvider {
static ProductDataBaseProvider? _productDataBaseProvider;
ProductDataBaseProvider._internal();

factory ProductDataBaseProvider() {
return _productDataBaseProvider ?? ProductDataBaseProvider._internal();
}

String get boxName => "product";


Future<bool> insertProduct({required ProductModel product}) async {
Box<ProductModel> productBox = await Hive.openBox(boxName);
int effectedRows = await productBox.add(product);
return effectedRows > 0;
}

Future<List<ProductModel>> fetchProducts() async {
Box<ProductModel> productBox = await Hive.openBox(boxName);
List<ProductModel> products = productBox.values.toList();
return products;
}

Future<void> updateProduct(
{required int index, required ProductModel product}) async {
Box<ProductModel> productBox = await Hive.openBox(boxName);
return productBox.putAt(index, product);
}

Future<void> deleteProduce({required int index}) async {
Box<ProductModel> productBox = await Hive.openBox(boxName);
return productBox.deleteAt(index);
}
}

Now you have to add the below package of the path_provider to set the path of the local database .

Now you have to make the main function of your app async and add the following lines inside it .

WidgetsFlutterBinding.ensureInitialized();
Directory directory = await getApplicationDocumentsDirectory();
Hive.initFlutter(directory.path);
Hive.registerAdapter(ProductAdaptor());

void main() async {
WidgetsFlutterBinding.ensureInitialized();
Directory directory = await getApplicationDocumentsDirectory();
Hive.initFlutter(directory.path);
Hive.registerAdapter(ProductAdaptor());
runApp(const MyApp());
}

Now you have to write the code for the insert and fetch data of the model class .

First off all you have to make the constructor of the database provider class and then insert the data

Now using the insert method of the database provider class you have to insert the data model inside it .



ProductDataBaseProvider _productDataBaseProvider = ProductDataBaseProvider();
int _counter = 0 ;
void addProduct() async {
print("enter in add");

ProductModel _productModel = ProductModel(
productId: _counter,
productName: "Pizza",
productPrice: 200.23,
productImageUrl: "productImageUrl");

bool isInsert =
await _productDataBaseProvider.insertProduct(product: _productModel);
print("Result of product addition : $isInsert");
setState(() {
_counter = _counter + 1;
});
}

Now you have to write the code of fetching the data of the database .

List<ProductModel> products = [];

void fetchProducts() async {
print("Enter in fetch before data : $products");
products = await _productDataBaseProvider.fetchProducts();
print("Products Data : $products");
}

Now you only have to call that above two function’s for the insertion and fetching of the data . In the same way you have to write the code for the remaining operation’s of updating and deleting data in the data model

That’s all for the Hive local database

I hope you have learned a lot of new thing 😊

Thanks for reading 📚

--

--