Hive flutter

Hive flutter DEFAULT

Handling local data persistence in Flutter with Hive

Storing data locally and persisting between app launches is one of the fundamental concepts of any mobile app development process. Almost every app requires that you handle data — from storing customer information for a food delivery app, to the number of points scored in a game or a simple value to understand whether the user has turned on dark mode during their last visit.

Flutter provides many local data persistence options for developers to choose from. shared_preferences is a good package for storing small key-value pairs locally, and sqflite, the SQLite package for Flutter, is a good choice when you’re dealing with strong relational data that requires you to handle complex relationships in the database.

But if you want a fast and secure local database with no native dependencies that also runs on Flutter web (😉), then Hive is a pretty good choice.

In this article, you will learn how to get started with Hive before we build a simple app using Flutter. We will also look into a concept that allows you to handle simple relational data in Hive.

Why Hive?

Let’s first take a look at why you should choose Hive over the other solutions available for persisting data locally in Flutter.

Hive is a lightweight and fast key-value database solution that is cross-platform (runs on mobile, desktop, and web) and is written in pure Dart. This gives it an instant advantage over sqflite, which doesn’t support Flutter web — Hive has no native dependencies, so it runs seamlessly on the web.

Below is a graph that benchmarks Hive against other similar database solutions:

Hive benchmark graph

Hive also allows you to store custom classes using TypeAdapters. We will take a look at this in more detail later in the article.

Getting started with Hive

Let’s build a basic app where our users’ details are stored and where add, read, update, and delete operations on the data can be performed.

A view of all three screens in the final sample app

Create a new Flutter project using the following command:

flutter create hive_demo

You can open the project using your favorite IDE, but for this example, I’ll be using VS Code:

code hive_demo

Add the Hive and hive_flutter packages to your file:

dependencies: hive: ^2.0.4 hive_flutter: ^1.1.0

Replace the content of your file with the following:

import 'package:flutter/material.dart'; main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Hive Demo', theme: ThemeData( primarySwatch: Colors.purple, ), debugShowCheckedModeBanner: false, home: InfoScreen(), ); } }

The will display the details of the user — we will take a look at it in a moment. Before that, let’s understand an important concept used by Hive.

Understanding boxes

Hive uses the concept of “boxes” for storing data on the database. A box is similar to a table in an SQL database, except that boxes lack a strict structure. This means boxes are flexible and can only handle simple relationships between data.

We’ll only cover the typical Hive box in this tutorial, but it’s worth mentioning that you can create lazy boxes and encrypted boxes as well.

Initialize Hive

Before moving on to the CRUD operations of the database, you have to initialize Hive and open a box that will be used for storing the data.

Hive should be initialized before we load any boxes, so it’s best to initialize it inside the function of your Flutter app to avoid any errors. Note that if you are using Hive in a non-Flutter, pure Dart app, you should use to initialize Hive.

main() async { // Initialize hive await Hive.initFlutter(); runApp(MyApp()); }

Make the main function asynchronous and use to initialize Hive.

Now, you have to open a Hive box. If you plan to use multiple boxes in your project, note that you should open a box before using it.

In this app, we’ll use a single box that we’ll open just after Hive completes initialization.

main() async { // Initialize hive await Hive.initFlutter(); // Open the peopleBox await Hive.openBox('peopleBox'); runApp(MyApp()); }

We are now ready to perform CRUD operations on the local database.

Performing CRUD operations

We will define the basic CRUD operations in the StatefulWidget. The structure of this class will be as follows:

import 'package:flutter/material.dart'; import 'package:hive/hive.dart'; class InfoScreen extends StatefulWidget { @override _InfoScreenState createState() => _InfoScreenState(); } class _InfoScreenState extends State<InfoScreen> { late final Box box; @override void initState() { super.initState(); // Get reference to an already opened box box = Hive.box('peopleBox'); } @override void dispose() { // Closes all Hive boxes Hive.close(); super.dispose(); } @override Widget build(BuildContext context) { return Container(); } }

First, we retrieve a reference to the box inside the method that we had opened earlier. You should always close the opened boxes after you are done using them and before closing the application.

As we currently only require the box inside this widget, we can close the box inside the method of this class.

Let’s create some methods for performing the CRUD operations.

class _InfoScreenState extends State<InfoScreen> { late final Box box; _addInfo() async { // Add info to people box } _getInfo() { // Get info from people box } _updateInfo() { // Update info of people box } _deleteInfo() { // Delete info from people box } // ... }

Now we’ll build a very basic UI so that we can test out whether or not the operations are working properly.

class _InfoScreenState extends State<InfoScreen> { // ... @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('People Info'), ), body: Center( child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ ElevatedButton( onPressed: _addInfo, child: Text('Add'), ), ElevatedButton( onPressed: _getInfo, child: Text('Get'), ), ElevatedButton( onPressed: _updateInfo, child: Text('Update'), ), ElevatedButton( onPressed: _deleteInfo, child: Text('Delete'), ), ], ), ), ); } }

The app will look like this:

The basic UI we created to perform CRUD operations

Storing data

If you need to store data, you can use the reference to the Hive box and call on it. This method accepts a key-value pair.

// Add info to people box _addInfo() async { // Storing key-value pair box.put('name', 'John'); box.put('country', 'Italy'); print('Info added to box!'); }

Here, we have stored two key-value pairs, the Name of the person and their Home Country.

Hive also supports integer keys, so you can use auto-incrementing keys. This can be useful if you are storing multiple values (kinda similar to a list) and want to retrieve by their indices. You can store like this:

box.add('Linda'); // index 0, key 0 box.add('Dan'); // index 1, key 1

Retrieving data

To read data, you can use the method on the box object. You just have to provide the for retrieving its value.

// Read info from people box _getInfo() { var name = box.get('name'); var country = box.get('country'); print('Info retrieved from box: $name ($country)'); }

If you are using auto-incrementing values, you can read using the index, like this:

box.getAt(0); // retrieves the value with index 0 box.getAt(1); // retrieves the value with index 1

Updating data

To update the data of a particular key, you can use the same method that you originally used to store the value. This will update the value present at that key with the newly provided value.

// Update info of people box _updateInfo() { box.put('name', 'Mike'); box.put('country', 'United States'); print('Info updated in box!'); }

If you are using auto-incrementing values, you can use the method for updating the value present at a particular index.

box.putAt(0, 'Jenifer');

Deleting data

For deleting data, you can use the method by providing the key.

// Delete info from people box _deleteInfo() { box.delete('name'); box.delete('country'); print('Info deleted from box!'); }

This will delete the values present at those particular keys. Now, if you try to call the method using these keys, it will return null values.

If you are using auto-incrementing values, you can use method by providing the index.

box.deleteAt(0);

Using custom objects with TypeAdapter

In general, Hive supports all primitive types like , , , and . But sometimes you may need to store custom model classes that make data management easier.

To do this, you can take advantage of a TypeAdapter, which generates the and binary methods.

TypeAdapters can either be written manually or generated automatically. It’s always better to use code generation to generate the required methods because it helps to prevent any mistakes that might occur while writing manually (and also it’s faster).

The model class that we’ll be using for storing data is as follows:

class Person { final String name; final String country; Person({ required this.name, required this.country, }); }

Generating the Hive adapter

You will need to add some dependencies to generate the TypeAdapter for Hive. Add the following to your file:

dev_dependencies: hive_generator: ^1.1.0 build_runner: ^2.0.6

Annotate the model class to use code generation:

import 'package:hive/hive.dart'; part 'people.g.dart'; @HiveType(typeId: 1) class People { @HiveField(0) final String name; @HiveField(1) final String country; People({ required this.name, required this.country, }); }

You can then trigger code generation using the following command:

flutter packages pub run build_runner build

Registering the TypeAdapter

You should register the TypeAdapter before opening the box that is using it — otherwise, it will produce an error. As we are just using a single box and have opened it inside the function, we have to register the adapter before that.

main() async { // Initialize hive await Hive.initFlutter(); // Registering the adapter Hive.registerAdapter(PersonAdapter()); // Opening the box await Hive.openBox('peopleBox'); runApp(MyApp()); }

Now, you can directly perform database operations using this custom class.

Building the final app

The final app will mainly consist of three screens:

  1. AddScreen: for storing the user’s information on the database
  2. InfoScreen: for showing the user’s information that is present in the Hive database, and a button for deleting the user’s data
  3. UpdateScreen: for updating the user’s information on the database

You do not need to modify the file containing the widget and the function.

AddScreen

The will display a form for taking the user’s data as inputs. In our case, we will be inputting just two values, Name and the Home Country. At the bottom will be a button for sending the data to Hive.

The AddScreen

The code for the is as follows:

class AddScreen extends StatefulWidget { @override _AddScreenState createState() => _AddScreenState(); } class _AddScreenState extends State<AddScreen> { @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, appBar: AppBar( title: Text('Add Info'), ), body: Padding( padding: const EdgeInsets.all(16.0), child: AddPersonForm(), ), ); } }

is the main widget where the UI for the form is create. It also contains the Hive storage functionality.

The basic structure of the widget will look like this:

class AddPersonForm extends StatefulWidget { const AddPersonForm({Key? key}) : super(key: key); @override _AddPersonFormState createState() => _AddPersonFormState(); } class _AddPersonFormState extends State<AddPersonForm> { late final Box box; @override void initState() { super.initState(); // Get reference to an already opened box box = Hive.box('peopleBox'); } @override Widget build(BuildContext context) { return Container(); } }

We have retrieved a reference to the box inside the method. Now, we have to define a global key for the form and add some text editing controllers.

class _AddPersonFormState extends State<AddPersonForm> { final _nameController = TextEditingController(); final _countryController = TextEditingController(); final _personFormKey = GlobalKey<FormState>(); // ... }

Define a method for storing data to Hive and add a text field validator:

class _AddPersonFormState extends State<AddPersonForm> { // ... // Add info to people box _addInfo() async { Person newPerson = Person( name: _nameController.text, country: _countryController.text, ); box.add(newPerson); print('Info added to box!'); } String? _fieldValidator(String? value) { if (value == null || value.isEmpty) { return 'Field can\'t be empty'; } return null; } // ... }

The code for the UI is as follows:

class _AddPersonFormState extends State<AddPersonForm> { // ... @override Widget build(BuildContext context) { return Form( key: _personFormKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Name'), TextFormField( controller: _nameController, validator: _fieldValidator, ), SizedBox(height: 24.0), Text('Home Country'), TextFormField( controller: _countryController, validator: _fieldValidator, ), Spacer(), Padding( padding: const EdgeInsets.fromLTRB(8.0, 0.0, 8.0, 24.0), child: Container( width: double.maxFinite, height: 50, child: ElevatedButton( onPressed: () { if (_personFormKey.currentState!.validate()) { _addInfo(); Navigator.of(context).pop(); } }, child: Text('Add'), ), ), ), ], ), ); } }

UpdateScreen

The will be similar to the , but here we’ll pass the object to show the current value in the text fields.

The UpdateScreen

The code for this screen will be as follows:

class UpdateScreen extends StatefulWidget { final int index; final Person person; const UpdateScreen({ required this.index, required this.person, }); @override _UpdateScreenState createState() => _UpdateScreenState(); } class _UpdateScreenState extends State<UpdateScreen> { @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, appBar: AppBar( title: Text('Update Info'), ), body: Padding( padding: const EdgeInsets.all(16.0), child: UpdatePersonForm( index: widget.index, person: widget.person, ), ), ); } }

The only difference in the widget is that it will contain a method for updating the value present in the Hive database.

class _UpdatePersonFormState extends State<UpdatePersonForm> { late final _nameController; late final _countryController; late final Box box; // ... // Update info of people box _updateInfo() { Person newPerson = Person( name: _nameController.text, country: _countryController.text, ); box.putAt(widget.index, newPerson); print('Info updated in box!'); } @override void initState() { super.initState(); // Get reference to an already opened box box = Hive.box('peopleBox'); // Show the current values _nameController = TextEditingController(text: widget.person.name); _countryController = TextEditingController(text: widget.person.country); } @override Widget build(BuildContext context) { return Form( // ... ); } }

InfoScreen

The will be responsible for displaying the data stored in Hive. Basically, the operation will be performed here.

The InfoScreen

Hive provides a widget called that only refreshes when any value inside the database is modified.

This screen will contain some additional functionalities:

  • Tapping the Delete button next to each list item will removing the user’s data from the database
  • Tapping each list item will navigate to the
  • Tapping the floating action button in the bottom right will bring you to the

The code for this screen is as follows:

class InfoScreen extends StatefulWidget { @override _InfoScreenState createState() => _InfoScreenState(); } class _InfoScreenState extends State<InfoScreen> { late final Box contactBox; // Delete info from people box _deleteInfo(int index) { contactBox.deleteAt(index); print('Item deleted from box at index: $index'); } @override void initState() { super.initState(); // Get reference to an already opened box contactBox = Hive.box('peopleBox'); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('People Info'), ), floatingActionButton: FloatingActionButton( onPressed: () => Navigator.of(context).push( MaterialPageRoute( builder: (context) => AddScreen(), ), ), child: Icon(Icons.add), ), body: ValueListenableBuilder( valueListenable: contactBox.listenable(), builder: (context, Box box, widget) { if (box.isEmpty) { return Center( child: Text('Empty'), ); } else { return ListView.builder( itemCount: box.length, itemBuilder: (context, index) { var currentBox = box; var personData = currentBox.getAt(index)!; return InkWell( onTap: () => Navigator.of(context).push( MaterialPageRoute( builder: (context) => UpdateScreen( index: index, person: personData, ), ), ), child: ListTile( title: Text(personData.name), subtitle: Text(personData.country), trailing: IconButton( onPressed: () => _deleteInfo(index), icon: Icon( Icons.delete, color: Colors.red, ), ), ), ); }, ); } }, ), ); } }

Congratulations 🥳, you have completed your Flutter app using Hive as the local persistent database.

A demo of the final app is shown below:

Final demo of the Flutter app using Hive

Conclusion

This article covers almost all of the important, basic concepts of Hive. There are a few more things you can do with the Hive database, including storing simple relational data. Simple relationships between data can be handled using HiveList, but if you are storing any sensitive data to Hive, then you should check out their encrypted box.

In a nutshell, Hive is one of the best choices you have for local data persistence in Flutter, especially considering that it’s blazing fast and supports almost all platforms.

Thank you for reading the article! If you have any suggestions or questions about the article or examples, feel free to connect with me on Twitter or LinkedIn. You can also find the repository of the sample app on my GitHub.

LogRocket: Full visibility into your web apps

LogRocket Dashboard Free Trial Banner

LogRocket is a frontend application monitoring solution that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.

In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.

Try it for free.
Sours: https://blog.logrocket.com/handling-local-data-persistence-flutter-hive/

Blog

Purpose of the article: To educate beginners and flutter developers to work with the Hive DB for local storage of the application data 

Intended Audience: Flutter Enthusiasts

Tools and Technology: Android Studio, Flutter SDK

Keywords: Local Database, Hive, Flutter, Storage

Hive is a dart package used in Flutter applications for storing data locally and manipulating the data on a targeted device. Among several existing packages (Example: Floor, Moor, sqflite), Hive stands out to be very fast in CRUD operations, and at the same time, it stores the data securely using AES-256 (a robust encryption standard) encryption. This way, we can replace the dependency on popular flutter traditional packages like ‘shared_preferences’ and ‘flutter_secure_storage’ both at once. 

In this post, I will explain the implementation and demonstrate the usage of the package in a To-Do application. 

Add Dependencies

  1. Go to your project directory and the below in ‘pubspec.yaml’ file 

          dependencies:

          hive: ^2.0.4 

          hive_flutter: ^1.1.0 

          dev_dependencies: 

          hive_generator: ^1.1.0 

          build_runner: ^2.0.6 

Creating and registering a Type Adapter 

  1. Hive can store data using dart primitive types, although in production, we deal with model objects; to deal with objects, we need to generate TypeAdapter. 
  1. For this project, we require a Task object for our To-Do App.  
  1. Create a task object.
  1. ‘typeID’ is the identity of the object for the Hive to find it. HiveField must be annotated on the required field names, with their unique id in parameters. 
  1. Open the terminal and generate the file by entering the following: Flutter packages pub run build_runner build 
  1. To work with the generated TypeAdapter, we have to register the adapter in ‘main()’. 
  1. After registering, we can use the power of the provider package for state management of the app, and Hive works with the provider efficiently. 

Creating Change Notifier

  1. Create a Change Notifier for the application. 
  1.  After creating the notifier, register the ‘ListenableProvider’ in the ‘main()’. 
  1.  And now we are ready to use this in our already created UI for the To-Do App. 
  1.  Clone the below Git-Repository to review the whole project. 

https://github.com/abhishekgokavarapu-abzy/mt_todo_app.git

Demo Gif of App

References/ Sources: 

  1. https://pub.dev/packages/hive 
  1. https://docs.hivedb.dev/#/ 
  1. https://medium.com/flutterdevs/hive-database-with-typeadapter-in-flutter-7390d0e515fa 
Sours: https://www.mouritech.com/resources/blogs-technical-article-hive-database-for-flutter-applications/
  1. Gz tale
  2. Avery labels 3x5
  3. Kbo scores
  4. Ford rebuild kit
  5. Knuckles chaotix art

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

 

 

Sours: https://codingwithdhrumil.com/2021/03/hive-flutter-local-database-example.html
Flutter Offline Mode - Caching API Data Using HIVE Database -

Fast, Enjoyable & Secure NoSQL Database

GitHub Workflow Status (branch)Codecov branchPub VersionGitHub

Hive is a lightweight and blazing fast key-value database written in pure Dart. Inspired by Bitcask.

If you need queries, multi-isolate support or links between objects check out Isar Database.

  • 🚀 Cross platform: mobile, desktop, browser
  • ⚡ Great performance (see benchmark)
  • ❤️ Simple, powerful, & intuitive API
  • 🔒 Strong encryption built in
  • 🎈 NO native dependencies
  • 🔋 Batteries included

Check out the Quick Start documentation to get started.

You can use Hive just like a map. It is not necessary to await .

Hive not only supports primitives, lists and maps but also any Dart object you like. You need to generate a type adapter before you can store objects.

Extending is optional but it provides handy methods like and .

Hive was written with Flutter in mind. It is a perfect fit if you need a lightweight datastore for your app. After adding the required dependencies and initializing Hive, you can use Hive in your project:

Boxes are cached and therefore fast enough to be used directly in the method of Flutter widgets.

1000 read iterations1000 write iterations
SharedPreferences is on par with Hive when it comes to read performance. SQLite performs much worse.Hive greatly outperforms SQLite and SharedPreferences when it comes to writing or deleting.

The benchmark was performed on a Oneplus 6T with Android Q. You can run the benchmark yourself.

*Take this benchmark with a grain of salt. It is very hard to compare databases objectively since they were made for different purposes.

Sours: https://pub.dev/packages/hive

Flutter hive

Flutter save data to local storage with Hive NoSQL database package

What is Hive?

Hive is an advanced NoSQL local database.

What is Box?

All data stored in Hive is organized in boxes. A box can be compared to a table in SQL, but it does not have a structure and can contain anything.

Boxes can also be encrypted to store sensitive data.

Hive can store both primitive data and objects.

This article consists of two-part

  1. Basic CRUD operations with primitives
  2. How to work with objects

How to use Hive?

add dependencies to your pubspec.yaml

dependencies:
hive: ^2.0.4
hive_flutter: ^1.1.0

dev_dependencies:
hive_generator: ^1.1.0
build_runner: ^2.1.2

init Hive before in main.dart

import 'package:hive_flutter/hive_flutter.dart';void main() async {
awaitHive.initFlutter();
runApp(MyApp());
}

First of all, you need to open your box

await Hive.openBox('boxName');

Now you can do CRUD operations

Create

You can save your data using key-value pair.

final box = Hive.box('boxName');// key, value
box.put('name', 'ehe');
box.put('age', 25);
box.put('friends', ['a','b','c']);
box.put(123, 'evet');// index, value
box.putAt(35, 'value')box.putAll({'name': 'ehe', 'mail': '[email protected]'});

you can also get directly without creating an instance

Hive.box('boxName').put('name', 'ehe');

Read

// if key does not exists return null
String name = box.get('name');// if key does not exists return defaultValue
double height = box.get('height', defaultValue: 35);// get from index
box.get(35);

Update

Just overwrite again the value over the key

Delete

// delete key
box.delete('key');// delete keys
box.deleteAll(['key1','key2']);// delete index
box.deleteAt(35);// delete whole box
box.deleteFromDisk();// if the box contains the key return true, else false
final containsKey = box.containsKey('key');// get all keys in box
final keys = box.keys;// get all values in box
final values = box.values;// clear box
box.clear();

You can also store objects in Hive easily!!

Step 1: Create your object

Step 2: Generate adapters

run this command in your project

flutter packages pub run build_runner build

Step 3: Register the adapters and open a box

You need to register all enum and object adapters that you want to use

void main() async {
await Hive.initFlutter(); ... Hive.registerAdapter(PersonAdapter());
Hive.registerAdapter(HairColorAdapter());
Hive.registerAdapter(PetAdapter());
await Hive.openBox<Person>('personList'); runApp(MyApp());
}

Step 4: Do CRUD operations

final box = Hive.box<Person>('personList');// You can also use auto-increment keys if you like. This is very useful for storing and accessing multiple objects. You can use a Box like a list.do// Create
box.add(person);// Read
final person = box.getAt(0);// Update
person.name = 'newName';
person.save();// Delete
box.deleteAt(0);

You can also listen to changes and instant update

// ValueListenable
ValueListenableBuilder
(
valueListenable: box.listenable(),
builder: (context, Box<Person> box, _) {
return ListView.builder(itemBuilder: (_, index) {
return Text(box.getAt(index)!.name);
}
);
},
),// Stream
box.watch().listen((event) => print(event));
Sours: https://itnext.io/flutter-save-data-to-local-storage-with-hive-nosql-database-package-8a0de834f313
Saving and Retrieving Data Using Hive in Flutter: Storing Primitive Data Types

You will tell me when youre done, the little man whispered in my ear with a fume, and then pressed his hard instrument to me, which looked more like a stick protruding from sweatpants. I'm done, - I said, and unscrewed the vice, putting the coveted hairpin on the table. Uncle Yura took a step aside, flipped the switch and turned off the light.

Come on, Sanka, get down on your knees, - the neighbor whispered quietly.

You will also like:

How he looked into my eyes and asked me to take it in my mouth. I realized that Irochka was not a competitor to me and took his. Penis into her mouth.



1064 1065 1066 1067 1068