13 KiB
Hive CE Database Setup - Worker App
Overview
The Worker Flutter app now has a complete Hive CE (Community Edition) database setup for offline-first functionality. This document provides a comprehensive summary of the setup.
What Was Created
1. Core Files
/lib/core/constants/storage_constants.dart
Centralized constants for Hive database:
- HiveBoxNames: All box names (13 boxes total)
- HiveTypeIds: Type adapter IDs (0-223 range, 32 IDs assigned)
- HiveKeys: Storage keys for settings and cache
- CacheDuration: Default cache expiration times
- HiveDatabaseConfig: Database configuration settings
/lib/core/database/hive_service.dart
Main database service handling:
- Hive initialization and configuration
- Type adapter registration (auto-generated)
- Box opening and management
- Database migrations and versioning
- Encryption support
- Maintenance and compaction
- Cleanup operations
/lib/core/database/database_manager.dart
High-level database operations:
- Generic CRUD operations
- Cache management with expiration
- Sync state tracking
- Settings operations
- Offline queue management
- Database statistics
/lib/core/database/hive_initializer.dart
Simple initialization API:
- Easy app startup initialization
- Database reset functionality
- Logout data cleanup
- Statistics helpers
/lib/core/database/database.dart
Export file for convenient imports
2. Models
/lib/core/database/models/enums.dart
Type adapters for all enums (10 enums):
MemberTier- Loyalty tiers (Gold, Platinum, Diamond)UserType- User categories (Contractor, Architect, Distributor, Broker)OrderStatus- Order states (6 statuses)ProjectStatus- Project states (5 statuses)ProjectType- Project categories (5 types)TransactionType- Loyalty transaction types (8 types)GiftStatus- Gift/reward states (5 statuses)PaymentStatus- Payment states (6 statuses)NotificationType- Notification categories (7 types)PaymentMethod- Payment methods (6 methods)
Each enum includes:
- Extension methods for display names
- Helper properties for state checking
- Vietnamese localization
/lib/core/database/models/cached_data.dart
Generic cache wrapper model:
- Wraps any data type with timestamp
- Expiration tracking
- Freshness checking
- Cache age calculation
3. Generated Files
/lib/hive_registrar.g.dart (Auto-generated)
Automatic adapter registration extension:
- Registers all type adapters automatically
- No manual registration needed
- Updates automatically when new models are added
/lib/core/database/models/*.g.dart (Auto-generated)
Individual type adapters for each model and enum
4. Configuration
pubspec.yaml
Updated dependencies:
dependencies:
hive_ce: ^2.6.0
hive_ce_flutter: ^2.1.0
dev_dependencies:
hive_ce_generator: ^1.6.0
build_runner: ^2.4.11
build.yaml
Build runner configuration for code generation
Database Architecture
Box Structure
The app uses 13 Hive boxes organized by functionality:
Encrypted Boxes (Sensitive Data):
user_box- User profile and authenticationcart_box- Shopping cart itemsorder_box- Order historyproject_box- Construction projectsloyalty_box- Loyalty transactionsaddress_box- Delivery addressesoffline_queue_box- Failed API requests
Non-Encrypted Boxes:
8. product_box - Product catalog cache
9. rewards_box - Rewards catalog
10. settings_box - App settings
11. cache_box - Generic API cache
12. sync_state_box - Sync timestamps
13. notification_box - Notifications
Type ID Allocation
Reserved type IDs (never change once assigned):
Core Models (0-9):
- 0: UserModel (TODO)
- 1: ProductModel (TODO)
- 2: CartItemModel (TODO)
- 3: OrderModel (TODO)
- 4: ProjectModel (TODO)
- 5: LoyaltyTransactionModel (TODO)
Extended Models (10-19):
- 10: OrderItemModel (TODO)
- 11: AddressModel (TODO)
- 12: CategoryModel (TODO)
- 13: RewardModel (TODO)
- 14: GiftModel (TODO)
- 15: NotificationModel (TODO)
- 16: QuoteModel (TODO)
- 17: PaymentModel (TODO)
- 18: PromotionModel (TODO)
- 19: ReferralModel (TODO)
Enums (20-29): ✓ Created
- 20: MemberTier
- 21: UserType
- 22: OrderStatus
- 23: ProjectStatus
- 24: ProjectType
- 25: TransactionType
- 26: GiftStatus
- 27: PaymentStatus
- 28: NotificationType
- 29: PaymentMethod
Cache & Sync Models (30-39):
- 30: CachedData ✓ Created
- 31: SyncState (TODO)
- 32: OfflineRequest (TODO)
How to Use
1. Initialize Hive in main.dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'core/database/hive_initializer.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// Initialize Hive database
await HiveInitializer.initialize(
verbose: true, // Enable logging in debug mode
);
runApp(
const ProviderScope(
child: MyApp(),
),
);
}
2. Basic Database Operations
import 'package:worker/core/database/database.dart';
// Get database manager instance
final dbManager = DatabaseManager();
// Save data
await dbManager.save(
boxName: HiveBoxNames.productBox,
key: 'product_123',
value: product,
);
// Get data
final product = dbManager.get(
boxName: HiveBoxNames.productBox,
key: 'product_123',
);
// Get all items
final products = dbManager.getAll(boxName: HiveBoxNames.productBox);
// Delete data
await dbManager.delete(
boxName: HiveBoxNames.productBox,
key: 'product_123',
);
3. Caching with Expiration
import 'package:worker/core/database/database.dart';
final dbManager = DatabaseManager();
// Save to cache with timestamp
await dbManager.saveToCache(
key: HiveKeys.productsCacheKey,
data: products,
);
// Get from cache (returns null if expired)
final cachedProducts = dbManager.getFromCache<List<Product>>(
key: HiveKeys.productsCacheKey,
maxAge: CacheDuration.products, // 6 hours
);
if (cachedProducts == null) {
// Cache miss or expired - fetch from API
final freshProducts = await api.getProducts();
await dbManager.saveToCache(
key: HiveKeys.productsCacheKey,
data: freshProducts,
);
}
4. Offline Queue
import 'package:worker/core/database/database.dart';
final dbManager = DatabaseManager();
// Add failed request to queue
try {
await api.createOrder(orderData);
} catch (e) {
await dbManager.addToOfflineQueue({
'endpoint': '/api/orders',
'method': 'POST',
'body': orderData,
});
}
// Process queue when back online
final queue = dbManager.getOfflineQueue();
for (var i = 0; i < queue.length; i++) {
try {
await api.request(queue[i]);
await dbManager.removeFromOfflineQueue(i);
} catch (e) {
// Keep in queue for next retry
}
}
5. Settings Management
import 'package:worker/core/database/database.dart';
final dbManager = DatabaseManager();
// Save setting
await dbManager.saveSetting(
key: HiveKeys.languageCode,
value: 'vi',
);
// Get setting
final language = dbManager.getSetting<String>(
key: HiveKeys.languageCode,
defaultValue: 'vi',
);
6. Sync State Tracking
import 'package:worker/core/database/database.dart';
final dbManager = DatabaseManager();
// Update sync timestamp
await dbManager.updateSyncTime(HiveKeys.productsSyncTime);
// Get last sync time
final lastSync = dbManager.getLastSyncTime(HiveKeys.productsSyncTime);
// Check if needs sync
final needsSync = dbManager.needsSync(
dataType: HiveKeys.productsSyncTime,
syncInterval: Duration(hours: 6),
);
if (needsSync) {
// Perform sync
await syncProducts();
await dbManager.updateSyncTime(HiveKeys.productsSyncTime);
}
7. Logout (Clear User Data)
import 'package:worker/core/database/hive_initializer.dart';
// Clear user data while keeping settings and cache
await HiveInitializer.logout();
Creating New Hive Models
Step 1: Create Model File
// lib/features/products/data/models/product_model.dart
import 'package:hive_ce/hive.dart';
import 'package:worker/core/constants/storage_constants.dart';
part 'product_model.g.dart';
@HiveType(typeId: HiveTypeIds.product) // Use typeId: 1
class ProductModel extends HiveObject {
@HiveField(0)
final String id;
@HiveField(1)
final String name;
@HiveField(2)
final String sku;
@HiveField(3)
final double price;
@HiveField(4)
final List<String> images;
@HiveField(5)
final String categoryId;
@HiveField(6)
final int stock;
ProductModel({
required this.id,
required this.name,
required this.sku,
required this.price,
required this.images,
required this.categoryId,
required this.stock,
});
}
Step 2: Generate Adapter
dart run build_runner build --delete-conflicting-outputs
This automatically:
- Generates
product_model.g.dartwithProductModelAdapter - Updates
hive_registrar.g.dartto register the new adapter - No manual registration needed!
Step 3: Use the Model
import 'package:worker/core/database/database.dart';
final product = ProductModel(
id: '123',
name: 'Ceramic Tile',
sku: 'TILE-001',
price: 299000,
images: ['image1.jpg'],
categoryId: 'cat_1',
stock: 100,
);
final dbManager = DatabaseManager();
await dbManager.save(
boxName: HiveBoxNames.productBox,
key: product.id,
value: product,
);
Important Rules
- Never change Type IDs - Once assigned, they are permanent
- Never change Field numbers - Breaks existing data
- Run build_runner after creating/modifying models
- Use the auto-generated registrar - Don't manually register adapters
- Always use try-catch around Hive operations
- Check box is open before accessing it
- Use DatabaseManager for high-level operations
- Set appropriate cache durations for different data types
Features
✓ Offline-First: All data stored locally and synced ✓ Type-Safe: Strong typing with generated adapters ✓ Fast: Optimized NoSQL database ✓ Encrypted: Optional AES encryption for sensitive data ✓ Auto-Maintenance: Compaction and cleanup ✓ Migration Support: Schema versioning built-in ✓ Cache Management: Automatic expiration handling ✓ Offline Queue: Failed request retry system ✓ Sync Tracking: Data freshness monitoring ✓ Statistics: Debug utilities for monitoring
Next Steps
To Complete the Database Setup:
- Create Model Classes for the TODO items (typeIds 0-19, 31-32)
- Run build_runner to generate adapters
- Implement sync logic in repository layers
- Add encryption in production (if needed)
- Test migrations when schema changes
- Monitor database size in production
Models to Create:
Priority 1 (Core):
- UserModel (typeId: 0)
- ProductModel (typeId: 1)
- CartItemModel (typeId: 2)
- OrderModel (typeId: 3)
Priority 2 (Extended):
- ProjectModel (typeId: 4)
- LoyaltyTransactionModel (typeId: 5)
- AddressModel (typeId: 11)
- NotificationModel (typeId: 15)
Priority 3 (Additional):
- OrderItemModel (typeId: 10)
- CategoryModel (typeId: 12)
- RewardModel (typeId: 13)
- GiftModel (typeId: 14)
- QuoteModel (typeId: 16)
- PaymentModel (typeId: 17)
- PromotionModel (typeId: 18)
- ReferralModel (typeId: 19)
Troubleshooting
Build Runner Fails
# Clean and rebuild
flutter clean
flutter pub get
dart run build_runner clean
dart run build_runner build --delete-conflicting-outputs
Box Not Found Error
- Ensure
HiveInitializer.initialize()is called in main.dart - Check box name matches
HiveBoxNamesconstant
Adapter Not Registered
- Run build_runner to generate adapters
- Check
hive_registrar.g.dartincludes the adapter - Ensure
Hive.registerAdapters()is called in HiveService
Data Corruption
- Enable backups before migrations
- Test migrations on copy of production data
- Validate data before saving
Resources
- Hive CE Documentation: https://github.com/IO-Design-Team/hive_ce
- Project README:
/lib/core/database/README.md - Storage Constants:
/lib/core/constants/storage_constants.dart - Type Adapter Registry: See README.md for complete list
Summary
The Hive CE database is now fully configured and ready to use. All enum type adapters are created and registered automatically. Future models will follow the same pattern - just create the model file with annotations and run build_runner to generate adapters.
The database supports offline-first functionality with:
- 13 pre-configured boxes
- 32 reserved type IDs
- Auto-generated adapter registration
- Cache management with expiration
- Offline request queuing
- Sync state tracking
- Maintenance and cleanup
Start creating models and building the offline-first features!