This document explains the Realm DB implementation in the Reader App for persisting:
- User feedback with sentiment ratings
- Favorite books
- User profile information (username and email)
- Realm Kotlin:
io.realm.kotlin:library-base:1.16.0 - Added to
build.gradle.ktswith the Realm plugin
Three Realm object models have been created:
-
FeedbackRealm
- Stores user feedback submissions
- Fields: feedback text, sentiment index (0-3), timestamp
-
FavoriteBookRealm
- Stores favorite books persistently
- Fields: book ID, title, author, subtitle, rating, cover image URL, user rating, description
-
UserProfileRealm
- Stores user profile information
- Fields: username, email, last updated timestamp
- Singleton pattern for database access
- Configured with schema version 1
- Database file:
reader_app.realm
The repository provides methods for:
Feedback Operations:
saveFeedback()- Save new feedbackgetAllFeedback()- Retrieve all feedback (Flow)deleteFeedback()- Delete specific feedback
Favorite Books Operations:
saveFavoriteBook()- Add book to favoritesremoveFavoriteBook()- Remove book from favoritesupdateBookRating()- Update user's rating for a bookgetAllFavoriteBooks()- Get all favorites as Flow<List>isFavorite()- Check if a book is favorited
User Profile Operations:
saveUserProfile()- Save/update username and emailgetUserProfile()- Get profile as FlowgetUserProfileOnce()- Get profile once (suspend function)
- Updated to use Realm DB for persistent storage
- Constructor now takes
RealmRepository - Favorites are loaded from Realm on initialization
- All favorite operations (add/remove/update rating) are persisted to Realm
- Uses Flow to automatically update UI when database changes
- Manages feedback submissions
- Loads all saved feedback
- Provides delete functionality
- Updated to include Realm DB storage
- Constructor now takes both
UserPreferencesandRealmRepository - Username is saved to multiple locations for redundancy:
- Realm DB (local persistent storage)
- UserPreferences (encrypted SharedPreferences)
- Firebase Firestore (cloud backup)
- Fallback hierarchy ensures username is always available
- Now saves feedback to Realm DB when submitted
- Uses
FeedbackViewModelto persist data - Shows confirmation message after saving
- Displays history of all submitted feedback
- Shows sentiment icon, rating, text, and timestamp
- Allows deletion of individual feedback items
- Empty state when no feedback exists
- Already displays favorite books
- Now powered by Realm DB for persistence
- Favorites survive app restarts
- Added
RealmRepositoryas singleton
- Updated
FavoritesViewModelto receiveRealmRepository - Added
FeedbackViewModelwithRealmRepository - Updated
UserProfileViewModelto receive bothUserPreferencesandRealmRepository
- Realm database initialized in
onCreate() - Happens before Koin initialization
New screen added to navigation:
- ViewFeedbackScreen - Route:
ReaderScreens.ViewFeedbackScreen
// In any composable with FeedbackViewModel injected
feedbackViewModel.saveFeedback("Great app!", sentimentIndex = 3)// In any composable with FavoritesViewModel injected
favoritesViewModel.addFavorite(book)
favoritesViewModel.removeFavorite(bookId)
favoritesViewModel.updateUserRating(bookId, 4.5)// In any composable with UserProfileViewModel injected
userProfileViewModel.updateUsername("John Doe")All data is exposed as StateFlow, making it easy to observe in Composables:
val favoriteBooks by favoritesViewModel.favoriteBooks.collectAsState()
val feedbackList by feedbackViewModel.feedbackList.collectAsState()
val username by userProfileViewModel.username.collectAsState()- Persistence: All data survives app restarts
- Offline Support: Works without internet connection
- Reactive: UI automatically updates when data changes (Flow/StateFlow)
- Type-Safe: Kotlin-first approach with compile-time safety
- Performance: Efficient queries and lazy loading
- Redundancy: User data saved to multiple locations (Realm, SharedPreferences, Firebase)
- Primary: Realm DB (local, fast access)
- Backup: Encrypted SharedPreferences
- Cloud: Firebase Firestore (if user is logged in)
- Storage: Realm DB only
- Synced: Automatically across all screens via singleton ViewModel
- Storage: Realm DB only
- Accessible: Via ViewFeedbackScreen
Potential improvements:
- Add Firebase sync for favorites (cross-device sync)
- Export feedback to CSV/JSON
- Add statistics dashboard for reading habits
- Implement data migration from Room to Realm (if needed)
- Add search/filter for feedback history
- Backup/restore functionality
To verify the implementation:
- Add books to favorites → Close app → Reopen → Favorites should persist
- Submit feedback → Navigate to ViewFeedbackScreen → See saved feedback
- Update username → Close app → Reopen → Username should persist
The Realm database file is stored at:
/data/data/com.example.reader/files/reader_app.realm
You can inspect it using Realm Studio for debugging.
- Realm operations are performed on background threads (suspend functions)
- UI updates happen automatically via Flow
- Database is initialized once at app startup
- All ViewModels use the same singleton RealmRepository instance
- Favorites ViewModel is also a singleton to maintain state across navigation