DatabaseModule

@Module
object 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:

  1. Single Instance: Database is created once and shared across the app (Singleton)

  2. Proper Configuration: Migration strategy is consistently applied

  3. Testability: Tests can provide a fake database implementation

  4. 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):

  1. Room detects a schema mismatch

  2. Deletes the existing database (all local data is lost)

  3. Creates a new database with the new schema

  4. 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

See also

Functions

Link copied to clipboard
@Singleton
@Provides
fun provideRoomDatabase(appContext: Context): JetpackDatabase

Provides the singleton Room database instance.