Open In App

Flutter – Store Data in Hive Local Database

Last Updated : 24 Sep, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Hive is a data storage in our phone where we can store data in boxes. We can store an integer, string, list of strings, Boolean, double, models, list of integers, etc. in Hive. Now let us discuss where we can implement these. The first we can use this is to save the user information user is logged in or not, and any id or user details so that users don’t have to log in again whenever a user open that app. You can store bigger data also but it will store for a particular device only. Hive is a NoSQL server where you can store a maximum number of data in any form.

Difference Between SharedPreferences and Hive

Hive

Shared Preferences

Store Maximum data in it

Limited to store smaller data

Store Data in any type of datatypes

Limited to some datatypes

Useful for Storing larger data

Useful for storing small data

Both works well.Its upto your requirement to choose which one is best suitable for you. For Shared Preferences you can refer this amazing article Flutter – SharedPreferences

Implementation

Step 1: Create a basic flutter project by command

Dart




flutter create .


Step 2: Add hive package in it

Dart




flutter pub add hive_flutter


Check latest package: https://pub.dev/packages/hive_flutter

Tips Add from visual studio code by Ctrl+shift+P or Command+shift+P then add dependency and type hive and enter.

Step 3: Initialise box you want to use for storing the data

Dart




Future main() async {
  // It is used so that void main function 
  // can be intiated after successfully
  // intialization of data
  WidgetsFlutterBinding.ensureInitialized();
  
  // To intialise the hive database
  await Hive.initFlutter();
  
  runApp(const MyApp());
}


It is better to keep it null So that it can manage itself for every platform

Step 4: Open the Box in main function

Dart




Future main() async {
  // It is used so that void main function can
  // be intiated after successfully intialization of data
  WidgetsFlutterBinding.ensureInitialized();
    
  // To intialise the hive database
  await Hive.initFlutter();
  
  // To open the user hive box
  await Hive.openBox(userHiveBox);
  
  runApp(const MyApp());
}


Basic UI for doing the CRUD operation

On first screen I will add 1 floating action button will add value to hive database and will have list where list which will show the saved value in hive and in that list tile there will be two button for edit and delete items/users and 1 variable for list stored in database.

Dart




import 'package:flutter/material.dart';
import 'package:hive_flutter_templates/hive_functions.dart';
  
class MainScreen extends StatefulWidget {
  const MainScreen({super.key});
  
  @override
  State<MainScreen> createState() => _MainScreenState();
}
  
class _MainScreenState extends State<MainScreen> {
  // Local Variable Where we save
  // the hive data of current context
  List myHiveData = [];
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text("CRUD Operations"),
          actions: [
            // To refreah the Data stored in Hive
            IconButton(
                onPressed: () {
                  
                },
                icon: const Icon(Icons.refresh))
          ],
        ),
        // To add or create the data in Hive
        floatingActionButton: FloatingActionButton.extended(
            label: const Text("Add Data"),
            icon: const Icon(Icons.add),
            onPressed: () {
            
            }),
        body: Padding(
          padding: const EdgeInsets.all(8.0),
          child: myHiveData.isEmpty // To show when no data is stored
              ? const Center(
                  child: Text(
                  "No Data is Stored",
                  style: TextStyle(fontSize: 20, fontWeight: FontWeight.w600),
                ))
              // To show when data is stored
              : Column(
                  children: List.generate(myHiveData.length, (index) {
                  final userData = myHiveData[index];
                  return Card(
                    child: ListTile(
                      title: // Show Name of user stored in data base
                          Text("Name : ${userData["name"]}"),
                      subtitle: // Show Email of user stored in data base
                          Text("Email : ${userData["email"]}"),
                      trailing: Row(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          // To edit the data stored
                          IconButton(
                              onPressed: () {
                              
                              },
                              icon: const Icon(Icons.edit)),
                          // To delete the data stored
                          IconButton(
                              onPressed: () {
                               
                              },
                              icon: const Icon(Icons.delete)),
                        ],
                      ),
                    ),
                  );
                }).toList()),
        ));
  }}


Let’s start doing CRUD operations for data storing in Hive

To add or update the data we will create 1 form which will open as bottom dialog box.

Dart




// TextFields' controllers for adding  or updating data
final TextEditingController _nameController = TextEditingController();
final TextEditingController _emailController = TextEditingController();
  
// dialog box to create or update the data in hive
void showForm(int? itemKey) async {
    // itemKey == null -> create new item
    // itemKey != null -> update an existing item
    if (itemKey != null) {
      // To find the existing item
      // in our local database
      final existingItem =
          myHiveData.firstWhere((element) => element['key'] == itemKey);
      _nameController.text = existingItem['name'];
      _emailController.text = existingItem['email'];
    }
  
    showModalBottomSheet(
        context: context,
        elevation: 5,
        isScrollControlled: true,
        builder: (_) => Container(
              padding: EdgeInsets.only(
                  bottom: MediaQuery.of(context).viewInsets.bottom,
                  top: 15,
                  left: 15,
                  right: 15),
              child: Column(
                mainAxisSize: MainAxisSize.min,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Center(
                      child: Text(
                    itemKey == null ? 'Create New' : 'Update',
                    style: const TextStyle(
                        fontSize: 22, fontWeight: FontWeight.w600),
                  )),
                  TextField(
                    controller: _nameController,
                    decoration: const InputDecoration(hintText: 'Name'),
                  ),
                  const SizedBox(
                    height: 10,
                  ),
                  TextField(
                    controller: _emailController,
                    keyboardType: TextInputType.number,
                    decoration: const InputDecoration(hintText: 'Email'),
                  ),
                  const SizedBox(
                    height: 20,
                  ),
                  ElevatedButton(
                    onPressed: () async {
                      // Save new item
                      if (itemKey == null) {
                        HiveFunctions.createUser({
                          "email": _emailController.text,
                          "name": _nameController.text
                        });
                      }
                      // update an existing item
                      if (itemKey != null) {
                        HiveFunctions.updateUser(itemKey, {
                          "email": _emailController.text,
                          "name": _nameController.text
                        });
                      }
                      // Clear the text fields
                      _nameController.text = '';
                      _emailController.text = '';
  
                      Navigator.of(context).pop(); // Close the bottom sheet
                      // To refresh the Data stored in Hive after updation
                      getHiveData();
                    },
                    child: Text(itemKey == null ? 'Create New' : 'Update'),
                  ),
                  const SizedBox(
                    height: 15,
                  )
                ],
              ),
            ));
  }


For better coding and understanding we will write all the hive functions in one class as separate file named as hive_functions.dart.

Dart




import 'package:hive_flutter/hive_flutter.dart';
import 'package:hive_flutter_templates/hive_box_constant.dart';
  
class HiveFunctions {
  // Box which will use to store the things
  static final userBox = Hive.box(userHiveBox);
}


Additionally we are using 1 more file for storing all box name so that we cannot have any confusion.

Dart




const String userHiveBox="User Box";
// Constant Name of Box where we will store details of user


Now we will add all the hive functions in the file named as hive_functions.dart

1. Create: This will create the box or added data in box

Sample Code

Dart




// Create or add single data in hive
  static createUser(Map data) {
   userBox.add(data);
  }
  
// Create or add multiple data in hive
  static addAllUser(List data) {
    userBox.addAll(data);
  }


2. Read: To read the data you have stored

Dart




// Get All data  stored in hive
  static List getAllUsers() {
    final data = userBox.keys.map((key) {
      final value = userBox.get(key);
      return {"key": key, "name": value["name"], "email": value['email']};
    }).toList();
  
    return data.reversed.toList();
  }
  
  // Get data for particular user in hive
  static Map getUser(int key) {
    return userBox.get(key);
  }


3. Update: Update the data which is already store

Dart




// update data for particular user in hive
  static updateUser(int key, Map data) {
    userBox.put(key, data);
  }


4. Delete: Delete the data which is stored already

Dart




// delete data for particular user in hive
  static deleteUser(int key) {
    return userBox.delete(key);
  }
  
  // delete data for particular user in hive
  static deleteAllUser(int key) {
    return userBox.deleteAll(userBox.keys);
  }


Source code for all functions is here

Dart




import 'package:hive_flutter/hive_flutter.dart';
import 'package:hive_flutter_templates/hive_box_constant.dart';
  
class HiveFunctions {
  // Box which will use to store the things
  static final userBox = Hive.box(userHiveBox);
  
  // Create or add single data in hive
  static createUser(Map data) {
   userBox.add(data);
  }
  
  // Create or add multiple data in hive
  static addAllUser(List data) {
    userBox.addAll(data);
  }
  
  // Get All data  stored in hive
  static List getAllUsers() {
    final data = userBox.keys.map((key) {
      final value = userBox.get(key);
      return {"key": key, "name": value["name"], "email": value['email']};
    }).toList();
  
    return data.reversed.toList();
  }
  
  // Get data for particular user in hive
  static Map getUser(int key) {
    return userBox.get(key);
  }
    
  // update data for particular user in hive
  static updateUser(int key, Map data) {
    userBox.put(key, data);
  }
    
  // delete data for particular user in hive
  static deleteUser(int key) {
    return userBox.delete(key);
  }
  
  // delete data for particular user in hive
  static deleteAllUser(int key) {
    return userBox.deleteAll(userBox.keys);
  }
  
}


Now we will call different functions on different onClick and initstate.

  1. We will call getAll function in initState
  2. Show form function in floating action button
  3. Update function in edit button
  4. Delete function in delete button.

Final Source Code after functions and UI

Dart




import 'package:flutter/material.dart';
import 'package:hive_flutter_templates/hive_functions.dart';
  
class MainScreen extends StatefulWidget {
  const MainScreen({super.key});
  
  @override
  State<MainScreen> createState() => _MainScreenState();
}
  
class _MainScreenState extends State<MainScreen> {
  // Local Variable Where we save 
  // the hive data of current context
  List myHiveData = [];
    
  // TextFields' controllers for adding  or updating data
  final TextEditingController _nameController = TextEditingController();
  final TextEditingController _emailController = TextEditingController();
    
  // To Update the data from Hive in local variable
  getHiveData() {
    myHiveData = HiveFunctions.getAllUsers();
    setState(() {});
  }
  
  @override
  void initState() {
    super.initState();
    // Update the initial data
    // when page is loading
    getHiveData();
  }
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text("CRUD Operations"),
          actions: [
            // To refreah the Data stored in Hive
            IconButton(
                onPressed: () {
                  getHiveData();
                },
                icon: const Icon(Icons.refresh))
          ],
        ),
        // To add or create the data in Hive
        floatingActionButton: FloatingActionButton.extended(
            label: const Text("Add Data"),
            icon: const Icon(Icons.add),
            onPressed: () {
              showForm(null);
            }),
        body: Padding(
          padding: const EdgeInsets.all(8.0),
          child: myHiveData.isEmpty // To show when no data is stored
              ? const Center(
                  child: Text(
                  "No Data is Stored",
                  style: TextStyle(fontSize: 20, fontWeight: FontWeight.w600),
                ))
              // To show when data is stored
              : Column(
                  children: List.generate(myHiveData.length, (index) {
                  final userData = myHiveData[index];
                  return Card(
                    child: ListTile(
                      title: //Show Name of user stored in data base
                          Text("Name : ${userData["name"]}"),
                      subtitle: //Show Email of user stored in data base
                          Text("Email : ${userData["email"]}"),
                      trailing: Row(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          // To edit the data stored
                          IconButton(
                              onPressed: () {
                                showForm(userData["key"]);
                              },
                              icon: const Icon(Icons.edit)),
                          // To delete the data stored
                          IconButton(
                              onPressed: () {
                                HiveFunctions.deleteUser(userData["key"]);
                                // To refreah the Data stored in Hive after deletion
                                getHiveData();
                              },
                              icon: const Icon(Icons.delete)),
                        ],
                      ),
                    ),
                  );
                }).toList()),
        ));
  }
  
// dialog box to create or update the data in hive
void showForm(int? itemKey) async {
    // itemKey == null -> create new item
    // itemKey != null -> update an existing item
  
    if (itemKey != null) {
      // To find the existing item in our  local database
      final existingItem =
          myHiveData.firstWhere((element) => element['key'] == itemKey);
      _nameController.text = existingItem['name'];
      _emailController.text = existingItem['email'];
    }
  
    showModalBottomSheet(
        context: context,
        elevation: 5,
        isScrollControlled: true,
        builder: (_) => Container(
              padding: EdgeInsets.only(
                  bottom: MediaQuery.of(context).viewInsets.bottom,
                  top: 15,
                  left: 15,
                  right: 15),
              child: Column(
                mainAxisSize: MainAxisSize.min,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Center(
                      child: Text(
                    itemKey == null ? 'Create New' : 'Update',
                    style: const TextStyle(
                        fontSize: 22, fontWeight: FontWeight.w600),
                  )),
                  TextField(
                    controller: _nameController,
                    decoration: const InputDecoration(hintText: 'Name'),
                  ),
                  const SizedBox(
                    height: 10,
                  ),
                  TextField(
                    controller: _emailController,
                    keyboardType: TextInputType.number,
                    decoration: const InputDecoration(hintText: 'Email'),
                  ),
                  const SizedBox(
                    height: 20,
                  ),
                  ElevatedButton(
                    onPressed: () async {
                      // Save new item
                      if (itemKey == null) {
                        HiveFunctions.createUser({
                          "email": _emailController.text,
                          "name": _nameController.text
                        });
                      }
  
                      // update an existing item
                      if (itemKey != null) {
                        HiveFunctions.updateUser(itemKey, {
                          "email": _emailController.text,
                          "name": _nameController.text
                        });
                      }
  
                      // Clear the text fields
                      _nameController.text = '';
                      _emailController.text = '';
  
                      Navigator.of(context).pop(); // Close the bottom sheet
                      // To refresh the Data stored in Hive after updation
                      getHiveData();
                    },
                    child: Text(itemKey == null ? 'Create New' : 'Update'),
                  ),
                  const SizedBox(
                    height: 15,
                  )
                ],
              ),
            ));
  }
}


Output

Image

1. Basic UI screen

Screenshot-2023-09-05-at-104505-PM

2. Form where we can add or update the data

Screenshot-2023-09-05-at-104837-PM

Video

Errors

1. Unhandled Exception: HiveError: You need to initialize Hive or provide a path to store the box.

Solution : You forgot to initialise the hive in main function

2. The following HiveError was thrown building Builder:

Box not found. Did you forget to call Hive.openBox()?

Solution : You forgot to open the box.

3. Unhandled exception: MissingPluginException(No implementation found for method getAll on channel plugins.flutter.io/hive_flutter)

Solution: Uninstall the application and reinstall it.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads