DatabaseModule
Hilt module providing the Room database instance.
Why This Module Exists
Room databases require explicit initialization with context and configuration. This module centralizes database creation to ensure:
Single Instance: Database is created once and shared across the app (Singleton)
Proper Configuration: Migration strategy is consistently applied
Testability: Tests can provide a fake database implementation
Lazy Initialization: Database is only created when first needed
Architecture Decision: Destructive Migration
This template uses .fallbackToDestructiveMigration(true), which means:
What It Does
When the database schema changes (entity fields added/removed/modified):
Room detects a schema mismatch
Deletes the existing database (all local data is lost)
Creates a new database with the new schema
Starts fresh with no data
Why This Is Acceptable During Development
Rapid Iteration: Schema can change frequently during development
Firebase Sync: This template syncs data with Firebase, so local data can be re-fetched
Simpler Development: No need to write migration code for every schema change
Fresh Start: Avoids corrupted data from incomplete migrations
Why This Is NOT Acceptable for Production
Data Loss: Users would lose all locally cached data on app update
Poor UX: Users would see empty screens until re-sync completes
Network Usage: All data must be re-downloaded after each schema change
Migration Strategy for Production
Before releasing to production, you MUST implement proper migrations:
val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(db: SupportSQLiteDatabase) {
db.execSQL("ALTER TABLE jetpack ADD COLUMN new_field TEXT")
}
}
Room.databaseBuilder(...)
.addMigrations(MIGRATION_1_2)
.build()Testing Migrations
@Test
fun testMigration1To2() {
helper.createDatabase(DB_NAME, 1).apply {
// Insert data with schema v1
close()
}
helper.runMigrationsAndValidate(DB_NAME, 2, true, MIGRATION_1_2)
}When to Remove Destructive Migration
Remove .fallbackToDestructiveMigration(true) and add proper migrations when:
Preparing for the first production release
Users have accumulated significant local data
Offline-first functionality becomes critical
Network re-sync is too slow or expensive