How to Handle Offline Data Storage with Flutter Hive

Biztech

By : Biztech

How to Handle Offline Data Storage with Flutter Hive1

Summary

When you develop Flutter applications, you can use online real-time synchronization with the database or offline synchronization. While online synchronization of data will ensure users can access data in real-time, the offline synchronization method is helpful for apps that can access data even in the offline mode.

For that, there are several Flutter database options SQLite, text/JSON files, Objectbox, shared preferences storage, and Hive database. In this blog, we will discuss one of the popular offline synchronization methods using the Flutter Hive database.

Want to learn how you should handle offline Hive storage? This is the blog for you!

Let’s see.

What is Flutter Hive?

Hive is a fast and lightweight key-value database written in Dart programming language. Since it is programmed keeping Flutter in mind, it can be seamlessly used as a data store for your Flutter application.

If your app doesn’t need real-time data synchronization and needs the data to be stored in the device, Hive database could be a preferable choice for you.

However, there are many alternatives available in the market today we have compared Hive with one of its competitor, Spark.

So, how do we compare Spark vs Hive? Let’s check!

Hive Spark
It’s a database, much like an RDBMS database, but the data is stored in boxes. It’s not a database but a data analytics framework.
Since it supports ANSI SQL standard, the hive integration capabilities are much higher. You can integrate it with databases like Cassandra and HBase. It can be integrated with Hive, MongoDB, and HBase.

 

Since we are looking for ways to handle offline data storage with Flutter app development, we will explore more about Hive going forward.

It is possible to use Hive like a map without awaiting Futures, like this:

var box = Hive.box('myBox');
box.put('name', 'David');
var name = box.get('name');
print('Name: $name');

With Hive, you can perform CRUD (Create, read, update, and delete) operations seamlessly. Here, look at some of the key features of Hive.

Read Also: Cross-platform App Development: Should Startups Invest in it or Not?

Hive Key Features

  • Since it is built keeping Flutter in mind, it is cross-platform with compatibility for browsers, mobile, and desktops.
  • Excellent performance.
  • No native dependencies.
  • Powerful in-built encryption.
  • Simple, intuitive, and robust API.
  • Batteries included.

Pros of Hive Database

  • You don’t have to write long pieces of code for data queries as it is easy to use, similar to Dart maps. Besides, the Dart programming language (also used in Flutter) has a simple learning curve.
  • There are no native dependencies so you don’t have to worry about compiling it for any specific platform.
  • Unlike other databases like SQLite, tables aren’t used in Hive. So, it is highly flexible and you can easily change the data structure as you find suitable.
  • It supports Dart objects using adapters as well as primitives like String, list, number, map, etc.
  • Hive Flutter is fast and usually can handle a significantly large amount of data.

Clearly, a hive database is quite a catch if you want to store data offline and retrieve it. But, how can you do so? It starts with the installation of hive and hive Flutter plugins.

Steps to Handle Offline Data Storage With Flutter Hive

Here, we will talk about using the Hive database with the help of TypeAdapter. The below steps will help you create a simple one-page Flutter application with offline handling of data. You will get to explore more about CRUD operations.

1. Install dependencies

It begins with the installation of dependencies such as Hive and Hive Flutter. To do so, you will have to add these packages to pubspec.yaml by writing the following code:

dependencies:
Flutter:
sdk: flutter
hive: ^2.2.3
hive_flutter: ^1.1.0

Then, add the development dependencies as below:

dev_dependencies:
flutter_test:
sdk: flutter
hive_generator: ^1.1.3
build_runner: ^2.2.0

2. Initialize Hive Flutter database

Before you call RunApp in Flutter, you will need to initialize Hive by writing below piece of code:

void main() async {
/*... */
await Hive.initFlutter();
/*...*/
}

“OR”

void main() async{
WidgetsFlutterBinding.ensureInitialized();
// This basically initializes the Flutter Hive with a valid directory in your application files
await Hive.initFlutter();
runApp(const MyApp());
}

3. Hive boxes

In Hive NoSQL, everything is stored and organized in boxes. To understand what these boxes are, you can simply compare them with the tables used in SQL.

However, unlike tables, they do not have any structure and can contain almost every kind of data. Here’s how you can work with a box in Hive!

To open a box, write:

await Hive.openBox('tool_box'); // Well, the name depends on you, change it as you please

When you open a box, all the data stored in Flutter local storage is loaded into the memory so users can access it immediately. You also don’t need to use await/async for retrieving data synchronously.

To retrieve data from box:

final myBox = Hive.box('tool_box');
final something = myBox.get('my_key');

To add new data/item to the box:

await myBox.put('some_key', someValue);

Update an existing data/item by writing:

await myBox.put('some_key', someValue);

Delete an item from the box using this code:

await myBox.delete('some_key');

To add a list of items in the Hive box, you can use the increment keys. Here, the keys will generate automatically and increment in the same way starting from ‘0’.

final listBox = Hive.box('my_list');
int newKey = await listBox.add(someData);

If you want to retrieve all of the keys from Hive boxes, you can do so by writing following piece of code:

final keys = listBox.keys;
final values = listBox.values;

You may as well use loops with the ‘Values’ and ‘Keys’ as required. And, if you need to set keys by yourself, you can use DateTime.now().toString().

These steps should help you code a Flutter app with Hive database. However, if you feel the coding and steps to be difficult, you can further hire Flutter developer to assist you with the app development.

4. Model Class with TypeAdapter

In this piece of code, several users with information like name, designation, and address are mentioned.

import 'package:hive/hive.dart';

part ‘user_model.g.dart’; // Used for generating TypeAdapter

@HiveType(typeId: 0) // So that generator gets an idea that it is a TypeAdapter
class UserModel extends HiveObject {
@HiveField(0) // annotating class field with their corresponding index values
final String name;
@HiveField(1)
final String designation;
@HiveField(2)
final String address;

UserModel({
required this.name,
required this.designation,
required this.address,
});
}

**Note: Since we are using the package hive_generator here, we do not need to construct the TypeAdapter manually.

If you want to build a TypeAdapter class, write this:

flutter packages pub run build_runner build

So, if your file name is user_demo.dart, you will get a file named user_demo.g.dart, where ‘g’ indicates that the file is generated successfully.

Now, you need to register UserDemoAdapter.

void main() async{
WidgetsFlutterBinding.ensureInitialized(); // Initializes Hive with a valid directory in your app files await Hive.initFlutter(); // Register Hive Adapter
Hive.registerAdapter(UserDemoAdapter()); // open box await Hive.openBox

5. CRUD operations

Creating data

You just have to call the add() function to add data in Hive. By using this method, a pair of key values is accepted.

// Adding a new user
Future addUser({required UserModel userModel}) async {
await box.add(userModel); }

After you click on the floating button, you will be able to see a dialog box. You can enter name, designation, and address (or any other details based on what you need) and click the ‘Add’ button. You should be able to see the data then.

You can also use ‘ValuelistenableBuilder()’ to check what’s happening inside a Hive box.

Retrieving Hive data

You can use the get() function to read the box objects. To retrieve the object value, you will have to provide the key by writing:

var userHobby = box.get('hobby');

However, if you use auto incrementing values, you will need to utilize the getAt(index) method for retrieving data.

var userData = box.getAt(index);
ValueListenableBuilder(
valueListenable: HiveDataStore.box.listenable(),
builder: (context, Box box, widget) {
return SafeArea(
child: box.length > 0 ? ListView.builder(
shrinkWrap: true,
itemCount: box.length,
itemBuilder: (BuildContext context, int index) {
var userData = box.getAt(index);
return Container(
padding: const EdgeInsets.all(10),
margin: const EdgeInsets.all(10),
decoration: BoxDecoration(color: Colors.grey.withOpacity(0.1),
border: Border.all(color: Colors.blue.shade900),
borderRadius: const BorderRadius.all(Radius.circular(10))),
child: Row(
children: [
Expanded(
flex: 1,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
IntrinsicHeight(
child: Row(
children: [
Text(userData.name, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w700),
),
VerticalDivider(color: Colors.blue.shade900,thickness: 2,),
Text(userData.description, style: const TextStyle(fontSize: 15, fontWeight: FontWeight.w500),
),
],
),
),
const SizedBox(height: 15),
RichText(text: TextSpan(text: 'Hobby: ', style: const TextStyle(color: Colors.black, fontSize: 16, fontWeight: FontWeight.w700),
children: [
TextSpan(text: userData.hobby, style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500)),
],
),
),
],
),
),
Expanded(
flex: 0,
child: Row(
children: [
InkWell(
onTap:(){
isUpdate.value = true;
nameEditingCtr.text = userData.name;
hobbyEditingCtr.text = userData.hobby;
descriptionEditingCtr.text = userData.description;
_showDialog(context,index);
},
child: Icon(Icons.edit, size: 30, color: Colors.blue.shade900,),
),
const SizedBox(width: 10),
InkWell(
onTap: ()async{
await showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('Are you sure you want to delete ${userData.name}?'),
actions: [
TextButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.blue.shade900),
elevation: MaterialStateProperty.all(3),
shadowColor: MaterialStateProperty.all(Colors.blue.shade900), //Defines shadowColor
),
onPressed: () {dataStore.deleteUser(index: index);},
child: const Text('Yes', style: TextStyle(color: Colors.white),
),
),
TextButton(
style: ButtonStyle(backgroundColor: MaterialStateProperty.all(Colors.blue.shade900),
elevation: MaterialStateProperty.all(3),
shadowColor: MaterialStateProperty.all(Colors.blue.shade900), //Defines shadowColor
),
onPressed: () {Navigator.of(context, rootNavigator: true).pop(); },
child: const Text('No',
style: TextStyle(color: Colors.white),
),
),
],
),
);
},
child: Icon(Icons.delete,size:30,color: Colors.blue.shade900,))
],
)),
],
),
);
}):const Center(child: Text("No Data Found"),));
}
)

Updating data

You can use the put() to update the existing value of key. To do so, you can write:

// updating user data
Future updateUser({required int index,required UserModel userModel}) async {
await box.putAt(index,userModel); }

Deleting data

Passing the key to the delete() will help delete data.

// delete user
Future deleteUser({required int index}) async {
await box.deleteAt(index); }

Here, the auto incrementing values method is used for deleting data in Hive. You can also utilize deleteAt(index) method for fleeting values using the index.

Flutter saves data locally with the help of Hive and it is one of the many advantages of the SDK. You can also check our Flutter pros and cons blog for more information.

Takeaway

With Flutter Hive, you will be able to manage offline data storage more seamlessly. It is an efficient way of managing data offline. So, if you want to build a simple app that requires offline data creation, retrieval, update, and delete, you can check out the steps mentioned here.

Furthermore, if you need any help with programming, you can trust our developers with the same. BiztechCS boasts a team of Flutter developers who are well versed in database technologies like Hive.

So, what are you waiting for? Connect with our team today!

FAQs

Is Flutter Hive encrypted?

Yes, Flutter Hive is strongly encrypted with AES-256. So, if you are wondering whether it is secure or not, it is secure.

How do I create a Hive adapter in Flutter?

You can use the following code to create an adapter in Flutter.

import 'package:hive/hive.dart';

part ‘user_model.g.dart’; // Used for generating TypeAdapter

@HiveType(typeId: 0) // So that generator gets an idea that it is a TypeAdapter
class UserModel extends HiveObject {
@HiveField(0) // annotating class field with their corresponding index values
final String name;
@HiveField(1)
final String designation;
@HiveField(2)
final String address;

UserModel({
required this.name,
required this.designation,
required this.address,
});
}

What is Hive in Flutter?

It is a NoSQL, fast, and lightweight database which can be seamlessly used for handling offline data storage. Hive is written in Dart and supports complex and primitive data structures.

What is Hive used for?

Hive is a fast and scalable database that you can use with your applications. If you want to build an application that needs to load offline data and retrieve them conveniently, you will be able to do the same with Hive.

How do I connect my Hive to Flutter?

Connecting your Hive database to Flutter involves a few key steps. First, integrate the Hive package into your Flutter project using your preferred package manager. Then, set up your Hive boxes and data models to match your database structure. Ensure you initialize Hive in your app’s entry point and open the desired boxes. Once the connection is established, you can perform CRUD (Create, Read, Update, Delete) operations on your data. Make sure to manage the Hive boxes properly and handle exceptions for a seamless data interaction between your Hive database and Flutter app

How do you store data locally in Flutter?

You can store data locally within your Flutter app using multiple options. Shared Preferences allow you to store simple key-value pairs for settings or preferences. For more complex data structures and querying capabilities, SQLite provides a local relational database solution. 

Whereas, Hive offers a lightweight NoSQL database, focusing on speed and efficiency. You can also store data in files using Dart’s File class, making it suitable for various formats like JSON or CSV. Depending on your app’s needs, you can choose the appropriate method or combine them to efficiently manage and store data locally within your Flutter application.

What is the difference between SQFLite and hive?

SQFLite and Hive are both local database solutions for Flutter, but they differ in their approach and features. SQFLite is a SQLite-based library that provides a traditional relational database, allowing you to structure data with tables, rows, and columns, and perform complex queries. It’s suitable for more intricate data needs and offers a wide range of querying capabilities. 

Whereas, Hive is a NoSQL database that prioritizes speed and simplicity. It employs lightweight data structures and operates directly with binary data, resulting in faster read/write operations. Hive is great for scenarios where performance is crucial and data structures are less complex.

How to sync the Flutter app's offline data with the online database efficiently?

Syncing offline data from a Flutter app to an online database involves multiple steps. First, utilize a local storage solution like Hive or SQLite to store data while offline. Implement a synchronization mechanism that detects changes in the local database and prepares them for upload. 

Use APIs or SDKs provided by the online database or backend to securely transmit data. Implement error handling and retry for network interruptions. To avoid data conflicts, consider incorporating strategies like server-generated timestamps, unique identifiers, or conflict resolution algorithms. Regularly synchronize in the background, respecting user preferences and connectivity. Testing, monitoring, and optimizing the synchronization process are vital to ensure smooth and reliable data transfer between the offline and online databases in your Flutter app.

Get a Free Consultation

    ✓ 100% Guaranteed Security of Your Information