Hive Flutter Local Database Example

In this article, we are going to learn how to use hive database in our flutter applications for local storage. Hive is lightweight and powerful database which runs fast in device and easy to integrate in flutter applications.

There are various options to store local data in flutter applications. We already implement sqlite database and shared preferences for flutter local storage. Hive is used for simple key value database. If we have complex data to store in local, we should use sqlite storage.

 

Add required dependencies in pubspec.yaml file

path_provider package is used for OS specific paths. hive_generator and build_runner are used to generate type adapter in flutter applications.

dependencies:
    hive: ^2.0.0
    path_provider: ^2.0.1
dev_dependencies:
    hive_generator: ^1.0.0
    build_runner: ^1.11.5
 
 

Initialize Hive Flutter Database

We need to first initialize hive database in main method before perform any database related operations.

Future<void> main() async {
    WidgetsFlutterBinding.ensureInitialized();
    Directory directory = await pathProvider.getApplicationDocumentsDirectory();
    Hive.init(directory.path);
    Hive.registerAdapter(EmployeeAdapter());
    runApp(MyApp());
}
 
 

Create TypeAdapter for Hive Flutter

To use custom model for our data, we need to generate and register type adapter in flutter applications. hive_generator and build_runner packages help us for this process.

import ‘package:flutter/material.dart’;
import ‘package:hive/hive.dart’;
part ’employee.g.dart’;

@HiveType(typeId: 0)
class Employee{

    @HiveField(0)
    String empName;

    @HiveField(1)
    String empSalary;

    @HiveField(2)
    String empAge;

    Employee({this.empName, this.empSalary, this.empAge});

}

 

Now add following command in terminal to generate type adapter.

flutter packages pub run build_runner build
 
 

Register TypeAdapter for Hive Flutter

Future<void> main() async {
    WidgetsFlutterBinding.ensureInitialized();
    Directory directory = await pathProvider.getApplicationDocumentsDirectory();
    Hive.init(directory.path);
    Hive.registerAdapter(EmployeeAdapter());
    runApp(MyApp());
}
 
 

Add Employee

To perform any database related operation, first we need to open box. Then we can perform any operation. We can add data by two ways. First one is add(value) method. add method auto increments keys for each item. If you want to set custom key for each item, you can use put(key,value) method.

Employee addEmployee = new Employee(
empName: getEmpName,
empSalary: getEmpSalary,
empAge: getEmpAge);
var box = await Hive.openBox<Employee>(’employee’);
box.add(addEmployee);
 
 

Get All Employees

We can get all employees data from hive database as below.

void getEmployees() async {
final box = await Hive.openBox<Employee>(’employee’);
setState(() {
    listEmployees = box.values.toList();
});
}
 
 

Update Employee

To update employee, we need to have unique key for each item. But we use auto incrementing keys for data. so here we use index to access particular employee. If you have custom key then you can use put(key,value) method.

Hive works as list in terms of index. If we delete some data then hive automatically update index keys of all data. So here we use index to update our employee.

Employee updateEmployee = new Employee(
empName: getEmpName,
empSalary: getEmpSalary,
empAge: getEmpAge);
var box = await Hive.openBox<Employee>(’employee’);
box.putAt(widget.position,updateEmployee);
 
 

Delete Employee

We can delete particular employee same as update employee using index as below.

final box = Hive.box<Employee>(’employee’);
box.deleteAt(position);
setState(() => {
    listEmployees.removeAt(position)
});
 
 

Final Code

 

main.dart

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutterhivesample/employee_list_screen.dart';
import 'package:hive/hive.dart';
import 'package:path_provider/path_provider.dart' as pathProvider;

import 'employee.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  Directory directory = await pathProvider.getApplicationDocumentsDirectory();
  Hive.init(directory.path);
  Hive.registerAdapter(EmployeeAdapter());
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: EmployeesListScreen(),
    );
  }
}
 

employee.dart

import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
part 'employee.g.dart';

@HiveType(typeId: 0)
class Employee{

  @HiveField(0)
  String empName;

  @HiveField(1)
  String empSalary;

  @HiveField(2)
  String empAge;

  Employee({this.empName, this.empSalary, this.empAge});

}
 

employee_list_screen.dart

import 'package:flutter/material.dart';
import 'package:flutterhivesample/employee.dart';
import 'package:hive/hive.dart';
import 'add_or_edit_employee_screen.dart';

class EmployeesListScreen extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return EmployeesListState();
  }
}

class EmployeesListState extends State<EmployeesListScreen> {
  List<Employee> listEmployees = [];

  void getEmployees() async {
    final box = await Hive.openBox<Employee>('employee');
    setState(() {
      listEmployees = box.values.toList();
    });
  }

  @override
  void initState() {
    getEmployees();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {

    return SafeArea(
      child: Scaffold(
        appBar: AppBar(
          title: Text("Flutter Hive Sample"),
          actions: <Widget>[
            IconButton(
              icon: Icon(Icons.add),
              onPressed: () {
                Navigator.push(context,
                    MaterialPageRoute(builder: (_) => AddOrEditEmployeeScreen(false)));
              },
            )
          ],
        ),
        body: Container(
            padding: EdgeInsets.all(15),
            child: ListView.builder(
                itemCount: listEmployees.length,
                itemBuilder: (context, position) {
                  Employee getEmployee = listEmployees[position];
                  var salary = getEmployee.empSalary;
                  var age = getEmployee.empAge;
                  return Card(
                    elevation: 8,
                    child: Container(
                      height: 80,
                      padding: EdgeInsets.all(15),
                      child: Stack(
                        children: <Widget>[
                          Align(
                              alignment: Alignment.topLeft,
                              child: Text(getEmployee.empName,
                                  style: TextStyle(fontSize: 18))),
                          Align(
                            alignment: Alignment.centerRight,
                            child: Container(
                              margin: EdgeInsets.only(right: 45),
                              child: IconButton(
                                  icon: Icon(Icons.edit),
                                  onPressed: () {
                                    Navigator.push(
                                        context,
                                        MaterialPageRoute(
                                            builder: (_) => AddOrEditEmployeeScreen(
                                                true, position, getEmployee)));
                                  }),
                            ),
                          ),
                          Align(
                            alignment: Alignment.centerRight,
                            child: IconButton(
                                icon: Icon(Icons.delete),
                                onPressed: (){
                                  final box = Hive.box<Employee>('employee');
                                  box.deleteAt(position);
                                  setState(() => {
                                    listEmployees.removeAt(position)
                                  });
                                }),
                          ),
                          Align(
                              alignment: Alignment.bottomLeft,
                              child: Text("Salary: $salary | Age: $age",
                                  style: TextStyle(fontSize: 18))),
                        ],
                      ),
                    ),
                  );
                })),
      ),
    );
  }
}
 

add_or_edit_employee_screen.dart

import 'package:flutter/material.dart';
import 'package:flutterhivesample/employee.dart';
import 'package:flutterhivesample/employee_list_screen.dart';
import 'package:hive/hive.dart';

class AddOrEditEmployeeScreen extends StatefulWidget {
  bool isEdit;
  int position;
  Employee employeeModel;

  AddOrEditEmployeeScreen(this.isEdit, [this.position,this.employeeModel]);

  @override
  State<StatefulWidget> createState() {
    return AddEditEmployeeState();
  }
}

class AddEditEmployeeState extends State<AddOrEditEmployeeScreen> {
  TextEditingController controllerName = new TextEditingController();
  TextEditingController controllerSalary = new TextEditingController();
  TextEditingController controllerAge = new TextEditingController();

  @override
  Widget build(BuildContext context) {

    if (widget.isEdit) {
      controllerName.text = widget.employeeModel.empName;
      controllerSalary.text = widget.employeeModel.empSalary.toString();
      controllerAge.text = widget.employeeModel.empAge.toString();
    }

    return SafeArea(
      child: Scaffold(
          body: SingleChildScrollView(
            child: Container(
              margin: EdgeInsets.all(25),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Row(
                    mainAxisAlignment: MainAxisAlignment.start,
                    children: <Widget>[
                      Text("Employee Name:", style: TextStyle(fontSize: 18)),
                      SizedBox(width: 20),
                      Expanded(
                        child: TextField(controller: controllerName),
                      )
                    ],
                  ),
                  SizedBox(height: 60),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.start,
                    children: <Widget>[
                      Text("Employee Salary:", style: TextStyle(fontSize: 18)),
                      SizedBox(width: 20),
                      Expanded(
                        child: TextField(
                            controller: controllerSalary,
                            keyboardType: TextInputType.number),
                      )
                    ],
                  ),
                  SizedBox(height: 60),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.start,
                    children: <Widget>[
                      Text("Employee Age:", style: TextStyle(fontSize: 18)),
                      SizedBox(width: 20),
                      Expanded(
                        child: TextField(
                            controller: controllerAge,
                            keyboardType: TextInputType.number),
                      )
                    ],
                  ),
                  SizedBox(height: 100),
                  RaisedButton(
                    color: Colors.grey,
                    child: Text("Submit",
                        style: TextStyle(color: Colors.white, fontSize: 18)),
                    onPressed: () async {
                      var getEmpName = controllerName.text;
                      var getEmpSalary = controllerSalary.text;
                      var getEmpAge = controllerAge.text;
                      if (getEmpName.isNotEmpty &amp;&amp;
                          getEmpSalary.isNotEmpty &amp;&amp;
                          getEmpAge.isNotEmpty) {
                        if (widget.isEdit) {
                          Employee updateEmployee = new Employee(
                              empName: getEmpName,
                              empSalary: getEmpSalary,
                              empAge: getEmpAge);
                          var box = await Hive.openBox<Employee>('employee');
                          box.putAt(widget.position,updateEmployee);
                        } else {
                          Employee addEmployee = new Employee(
                              empName: getEmpName,
                              empSalary: getEmpSalary,
                              empAge: getEmpAge);
                          var box = await Hive.openBox<Employee>('employee');
                          box.add(addEmployee);
                        }
                        Navigator.pushAndRemoveUntil(
                            context,
                            MaterialPageRoute(builder: (_) => EmployeesListScreen()),
                                (r) => false);
                      }
                    },
                  )
                ],
              ),
            ),
          )
      ),
    );
  }
}
 
 
 
 
hive flutter
 
hive flutter