------------------------- | Simple Hive Storage | ------------------------- | [TextField ] | | [Add Item Button ] | |-----------------------| | Items: | | 1. Example item | | 2. Another item | | | -------------------------
Hive for NoSQL storage in Flutter - Mini App: Build & Ship
import 'package:flutter/material.dart'; import 'package:hive/hive.dart'; import 'package:path_provider/path_provider.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); final appDocumentDir = await getApplicationDocumentsDirectory(); Hive.init(appDocumentDir.path); await Hive.openBox<String>('itemsBox'); runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return const MaterialApp( home: SimpleHiveStorageScreen(), ); } } class SimpleHiveStorageScreen extends StatefulWidget { const SimpleHiveStorageScreen({super.key}); @override State<SimpleHiveStorageScreen> createState() => _SimpleHiveStorageScreenState(); } class _SimpleHiveStorageScreenState extends State<SimpleHiveStorageScreen> { final TextEditingController _controller = TextEditingController(); late Box<String> itemsBox; @override void initState() { super.initState(); itemsBox = Hive.box<String>('itemsBox'); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Simple Hive Storage')), body: Padding( padding: const EdgeInsets.all(16), child: Column( children: [ TextField( controller: _controller, decoration: const InputDecoration(labelText: 'Enter new item'), ), const SizedBox(height: 10), ElevatedButton( onPressed: () { // TODO: Add item to Hive and update UI }, child: const Text('Add Item'), ), const SizedBox(height: 20), const Text('Items:'), Expanded( child: ValueListenableBuilder( valueListenable: Hive.box<String>('itemsBox').listenable(), builder: (context, Box<String> box, _) { if (box.isEmpty) { return const Center(child: Text('No items added yet')); } return ListView.builder( itemCount: box.length, itemBuilder: (context, index) { final item = box.getAt(index); return ListTile( title: Text(item ?? ''), onTap: () { // TODO: Delete tapped item }, ); }, ); }, ), ), ], ), ), ); } }
import 'package:flutter/material.dart'; import 'package:hive/hive.dart'; import 'package:path_provider/path_provider.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); final appDocumentDir = await getApplicationDocumentsDirectory(); Hive.init(appDocumentDir.path); await Hive.openBox<String>('itemsBox'); runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return const MaterialApp( home: SimpleHiveStorageScreen(), ); } } class SimpleHiveStorageScreen extends StatefulWidget { const SimpleHiveStorageScreen({super.key}); @override State<SimpleHiveStorageScreen> createState() => _SimpleHiveStorageScreenState(); } class _SimpleHiveStorageScreenState extends State<SimpleHiveStorageScreen> { final TextEditingController _controller = TextEditingController(); late Box<String> itemsBox; @override void initState() { super.initState(); itemsBox = Hive.box<String>('itemsBox'); } void _addItem() { final text = _controller.text.trim(); if (text.isNotEmpty) { itemsBox.add(text); _controller.clear(); } } void _deleteItem(int index) { itemsBox.deleteAt(index); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Simple Hive Storage')), body: Padding( padding: const EdgeInsets.all(16), child: Column( children: [ TextField( controller: _controller, decoration: const InputDecoration(labelText: 'Enter new item'), ), const SizedBox(height: 10), ElevatedButton( onPressed: _addItem, child: const Text('Add Item'), ), const SizedBox(height: 20), const Text('Items:'), Expanded( child: ValueListenableBuilder( valueListenable: itemsBox.listenable(), builder: (context, Box<String> box, _) { if (box.isEmpty) { return const Center(child: Text('No items added yet')); } return ListView.builder( itemCount: box.length, itemBuilder: (context, index) { final item = box.getAt(index); return ListTile( title: Text(item ?? ''), onTap: () => _deleteItem(index), ); }, ); }, ), ), ], ), ), ); } }
This app uses Hive to store a list of strings locally on the device. We initialize Hive with the app documents directory and open a box named 'itemsBox' to hold our strings.
The UI has a TextField to enter new items and a button to add them. When the button is pressed, the text is trimmed and added to the Hive box, then the TextField is cleared.
The list of stored items is shown below using a ValueListenableBuilder that listens to changes in the Hive box. This automatically updates the UI when items are added or deleted.
Tapping an item deletes it from the box, which also updates the list instantly.
This simple example shows how Hive can be used for local NoSQL storage with reactive UI updates in Flutter.
------------------------- | Simple Hive Storage | ------------------------- | [TextField ] | | [Add Item Button ] | |-----------------------| | Items: | | 1. Example item | | 2. Another item | | | -------------------------
Practice
Solution
Step 1: Understand Hive's role
Hive is designed as a local storage solution for Flutter apps, meaning it saves data on the device.Step 2: Compare with other options
Creating UI, handling network, and navigation are unrelated to data storage, so they are incorrect.Final Answer:
To store data locally in a simple way -> Option CQuick Check:
Hive = local data storage [OK]
- Confusing Hive with UI or network libraries
- Thinking Hive manages app navigation
- Assuming Hive is for remote databases
settings?Solution
Step 1: Recall Hive box opening syntax
Opening a box is asynchronous and requiresawait Hive.openBox('boxName').Step 2: Check options for async and method
var box = await Hive.openBox('settings');uses await and openBox correctly. Omitting await onHive.openBox('settings')returns a Future.Hive.box('settings')only accesses an already opened box synchronously, and awaitingHive.box('settings')is incorrect as it is synchronous.Final Answer:
var box = await Hive.openBox('settings'); -> Option AQuick Check:
Open box = await Hive.openBox() [OK]
- Forgetting await when opening a box
- Using Hive.box() before opening the box
- Awaiting Hive.box() which is synchronous
var box = await Hive.openBox('favorites');
await box.put('color', 'blue');
print(box.get('color'));Solution
Step 1: Understand put and get methods
Theputmethod saves a value with a key, here 'color' = 'blue'. Thegetmethod retrieves the value for the key.Step 2: Trace the code output
After putting 'blue' under 'color',box.get('color')returns 'blue', which is printed.Final Answer:
blue -> Option BQuick Check:
Put then get returns stored value [OK]
- Expecting get to return the key instead of value
- Thinking put is asynchronous but get is not
- Assuming get returns null if key exists
var box = Hive.openBox('settings');
await box.put('theme', 'dark');Solution
Step 1: Check box opening syntax
Hive.openBox is asynchronous and must be awaited to get the box instance.Step 2: Identify error cause
Without await, box is a Future, so calling put on it causes an error.Final Answer:
Missing await before Hive.openBox -> Option DQuick Check:
Always await openBox before using box [OK]
- Not awaiting openBox causing Future errors
- Thinking box name must be a number
- Misusing await outside async functions
favorites. Which code correctly saves and retrieves this list?Solution
Step 1: Check correct put syntax for list
Useawait box.put(key, value)with key as string and value as list to save data.Step 2: Retrieve list correctly
Usebox.get(key)synchronously to get saved list. Await is not needed for get.Final Answer:
await box.put('favorites', ['apple', 'banana']); var list = box.get('favorites'); -> Option AQuick Check:
Put list with await, get list without await [OK]
- Using list as key instead of string
- Awaiting get method which is synchronous
- Saving list as string instead of list
Ready to prove it?
Pass the test and this pattern moves unknown
