androidandroid-room

fallbackToDestructiveMigrationFrom not called because "A migration from 8 to 10 was required but not found"


I have several crashes reported from crashlytics:

java.lang.IllegalStateException - A migration from 8 to 10 was required but not found.
Please provide the necessary Migration path via RoomDatabase.Builder.addMigration(Migration ...)

I am using the fallbackToDestructiveMigrationFrom in this way:

fun buildDatabase(context: Context): OneDatabase {
        // Since Room is only used for FTS, destructive migration is enough because the tables
        // are cleared every time the app launches.
        // https://medium.com/androiddevelopers/understanding-migrations-with-room-f01e04b07929
        return Room.databaseBuilder(context, OneDatabase::class.java, databaseName)
            .fallbackToDestructiveMigrationFrom(1, 2, 3, 4, 5, 6, 7, 8)
            .fallbackToDestructiveMigrationOnDowngrade()
            .addMigrations(*allMigrations())
            .build()
    }

and the allMigrations fun is:

fun allMigrations() = arrayOf(
    MIGRATION_9_10, MIGRATION_10_11, MIGRATION_11_12
)

is not this enough to trigger fallbackToDestructiveMigrationFrom(...) if a migration from 8 to 10 is required? I'm lost.


Solution

  • I believe that the issue is exactly what the message says. That there is no defined way of handling a migration from 8 to 10. The fallback from 8 should in theory go from 8 to 9 but then the the control should revert not to the fallback handling but the migration handling for 9-10 and hence neither handler being considered suitable.

    Have you tried providing an 8-10 migration? Not sure if this would itself result in an issue (I guess that it might).

    You could always skip the need for an 8-10 by introducing a pre-room handling check and then migration from 8 to 9 (allowing 9-10 ....) if the current version is 8 and the expected version is 10.

    You can efficiently check the version number of the existing database file by looking at the 4 bytes at offset 60. These 4 bytes are the SQLite user_version which Room (and the inbuild SQLite API) utilises for the version number. The following is a link to an answer that includes a java method that returns the version number

    Detect Room Migration Completion

    The link also includes a less efficient method that retrieves the version number after opening the file as an SQLite database (closing it after the interrogation).