A Flutter application demonstrating offline-first architecture with automatic cloud synchronization using Firebase Realtime Database, Hive local storage, and connectivity monitoring.
- β Offline-First Architecture - All operations work without internet connection
- β Automatic Cloud Sync - Syncs to Firebase when online
- β Local Storage - Uses Hive for fast local data persistence
- β Real-time Connectivity Detection - Monitors network status with visual indicator
- β Sync Status Indicators - Shows whether notes are synced, local-only, or cloud-only
- β Manual Sync Control - Force sync or refresh data on demand
- β CRUD Operations - Create, read, update, and delete notes
- β Conflict Resolution - Handles sync conflicts with CRDT-based operations
dependencies:
flutter: sdk: flutter
offline_sync_engine: ^2.4.0 # Sync engine with CRDT support
hive: ^2.2.3 # Local NoSQL database
hive_flutter: ^1.1.0 # Hive Flutter integration
firebase_core: ^4.4.0 # Firebase initialization
firebase_database: ^12.1.3 # Firebase Realtime Database
connectivity_plus: ^7.0.0 # Network connectivity monitoring
uuid: ^4.5.2 # UUID generationβββββββββββββββββββ
β Flutter UI β
ββββββββββ¬βββββββββ
β
ββββββββββΌβββββββββ
β SyncService β (Singleton managing sync operations)
ββββββββββ¬βββββββββ
β
ββββββ΄ββββββ
β β
βββββΌββββ βββββΌβββββ
β Hive β βFirebaseβ
β Local β β Cloud β
βββββββββ ββββββββββ
lib/main.dart- UI and user interactionslib/sync.dart- Sync service managing local/cloud operationslib/model.dart- Data models (Note, NoteView, NoteSyncStatus)lib/local.dart- Hive database adapter for offline_sync_enginelib/cloud.dart- Firebase cloud adapter for offline_sync_enginelib/internet.dart- Connectivity monitoring service
- Go to Firebase Console
- Create a new project (or use existing)
- Enable Firebase Realtime Database
For Android:
- Download
google-services.jsonfrom Firebase Console - Place it in
android/app/google-services.json
For iOS:
- Download
GoogleService-Info.plistfrom Firebase Console - Place it in
ios/Runner/GoogleService-Info.plist
For Web:
- Run
flutterfire configureto generate Firebase options - Follow the prompts to configure web support
In Firebase Console β Realtime Database β Rules:
{
"rules": {
".read": true,
".write": true,
"notes": {
".indexOn": ["id"]
},
"operations": {
".indexOn": ["opId"]
}
}
}flutter pub get# Android
flutter run -d android
# iOS
flutter run -d ios
# Web
flutter run -d chrome-
Online Mode: Type your note and press "Add"
- Saves to local storage immediately
- Syncs to Firebase automatically
- Shows "Note added and synced to cloud" (green)
-
Offline Mode: Type your note and press "Add"
- Saves to local storage immediately
- Note appears with "Local Only" status (orange indicator)
- Will sync when internet connection is restored
Each note displays a status indicator:
- π’ Synced - Present in both local storage and Firebase
- π Local Only - Only in local storage, not yet synced to cloud
- π΅ Cloud Only - Only in Firebase, not in local storage
- Press the delete icon (ποΈ) on any note
- Note is removed from local storage immediately
- If online, also removed from Firebase
- If offline, deletion will sync when connection is restored
- Sync Button (β³) - Manually trigger sync with Firebase
- Refresh Button (π) - Reload notes from storage
The app bar shows real-time connection status:
- π’ Online - Connected to internet, auto-sync enabled
- π΄ Offline - No connection, using local storage only
Three Hive boxes are used:
-
notes- Stores note data{ "id": "uuid", "content": "Note text" } -
sync_operations- Tracks pending sync operations{ "opId": "uuid", "type": "create/update/delete", ... } -
deleted_notes- Tombstone records for deleted items{ "id": "uuid", "deletedAt": "timestamp", "cloudDeleted": false }
Firebase Realtime Database structure:
{
"notes": {
"note-uuid-1": {
"id": "note-uuid-1",
"content": "My first note"
},
"note-uuid-2": {
"id": "note-uuid-2",
"content": "Another note"
}
},
"operations": {
"op-uuid-1": {
"opId": "op-uuid-1",
"type": "create",
// ... other sync metadata
}
}
}-
Write Operations: When you add/update/delete a note:
- Saved to local Hive storage immediately (works offline)
- Operation queued in
sync_operationsbox - If online, attempt to write to Firebase
- If offline, operation stays queued
-
Automatic Sync: When internet connection is detected:
ConnectivityServicetriggers automatic sync- Queued operations pushed to Firebase
- Cloud data reconciled with local data
- Sync operations cleaned up after success
-
Conflict Resolution: Uses CRDT-based
offline_sync_engine- Operations are commutative (order-independent)
- Last-write-wins with timestamp-based resolution
- Deterministic merging across devices
- β Internet connection restored (automatic)
- β Manual sync button pressed
- β App startup (if online)
- β After each create/update/delete operation (if online)
-
Disable Internet:
- Android Emulator: Open Settings β Network & Internet β Turn off WiFi
- Device: Enable Airplane Mode
-
Add Notes: Create several notes while offline
-
Verify Local Storage: Notes should appear immediately with "Local Only" status
-
Restart App: Close and reopen - notes should persist
-
Enable Internet: Turn WiFi/data back on
-
Auto-Sync: Watch notes sync automatically, status changes to "Synced"
-
Check Firebase Console: Verify notes appear in Realtime Database under
/notes/
- Add Note: Type and add a note
- Console Output: Should show:
I/flutter: Note saved locally: abc-123 I/flutter: Note saved to Firebase: abc-123 I/flutter: Starting sync... I/flutter: Sync completed. - Firebase Console: Note should appear immediately
Enable debug logging to see sync operations:
// Already enabled in the app
print('Note saved locally: $id');
print('Note saved to Firebase: $id');
print('Starting sync...');
print('Sync completed.');-
Check Firebase Configuration:
- Verify
google-services.json(Android) orGoogleService-Info.plist(iOS) is present - Check Firebase Console for correct project ID
- Verify
-
Check Database Rules:
- Ensure rules allow write access
- Look for permission errors in console
-
Check Internet Connection:
- Verify connectivity indicator shows "Online"
- Test with
flutter run -vfor detailed logs
-
Check Hive Initialization:
- Ensure
Hive.initFlutter()runs before data operations - Check app storage permissions
- Ensure
-
Clear Cache (if needed):
flutter clean flutter pub get
If you see timeout errors when offline, ensure:
loadNotesWithStatus(isOnline: _isConnected)is passing correct connectivity status- Firebase calls are wrapped in
isOnlinechecks
β
Offline-First Design - App fully functional without internet
β
Optimistic UI Updates - Immediate user feedback
β
Error Handling - Graceful degradation on network errors
β
Status Indicators - Clear visual feedback of sync state
β
Data Persistence - Local storage ensures no data loss
β
Automatic Sync - Seamless cloud synchronization
β
CRDT Operations - Conflict-free distributed data structures
- User authentication with Firebase Auth
- Multi-device sync testing
- Conflict resolution UI for manual intervention
- Batch operations for better performance
- Offline indicator with pending operations count
- Export/import functionality
- Search and filter capabilities
- Note categories/tags
- Rich text editor support
This project is open source and available for educational purposes.
Contributions are welcome! Feel free to:
- Report bugs
- Suggest new features
- Submit pull requests
- Improve documentation
- Flutter Documentation
- Firebase Documentation
- Hive Documentation
- offline_sync_engine Package
- connectivity_plus Package
Built with β€οΈ using Flutter