# How to properly use SQLCipher 4.5.0 on Android?

**URL:** <https://discuss.zetetic.net/t/how-to-properly-use-sqlcipher-4-5-0-on-android/5262>\
**Category:** SQLCipher\
**Created:** [January 19, 2022, 10:47am UTC](https://discuss.zetetic.net/t/how-to-properly-use-sqlcipher-4-5-0-on-android/5262 "2022-01-19T10:47:23Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![robertszuba](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/robertszuba/32/1749_2.png) [@robertszuba](https://discuss.zetetic.net/u/robertszuba)\
**Post date:** [January 19, 2022, 10:47am UTC](https://discuss.zetetic.net/t/how-to-properly-use-sqlcipher-4-5-0-on-android/5262/1 "2022-01-19T10:47:24Z")

</div>

Hi. We were using SQLCipher 3.x and 4.x in our Android application. When migrating from version 3.x to version 4.x we were struggling a bit on how to properly migrate the database. We ended up with a code snippet:

```auto
  override fun migrateDatabase(file: File, password: String): SQLiteDatabase {
    return SQLiteDatabase.openOrCreateDatabase(file, password, null, MigrationHook())
  }

  // see https://discuss.zetetic.net/t/upgrading-to-sqlcipher-4/3283
  private class MigrationHook : SQLiteDatabaseHook {
    override fun preKey(database: SQLiteDatabase?) { /* not used */
    }

    override fun postKey(database: SQLiteDatabase?) {
      database?.rawExecSQL("PRAGMA cipher_migrate")
    }
  }

```

The code snippet was working fine. But now as we can read in 4.5.0 [release notes](https://www.zetetic.net/blog/2021/10/28/sqlcipher-4.5.0-release/) the `cipher_migrate` PRAGMA could fail and in such case the app would still work with the non-migrated version of the DB. With version 4.5.0 it is advised to actually check if the migration fails to prevent further read/write issues.

My question is what is the recommended way to verify if migration works fine? Should we still use the SQLiteDatabaseHook for the migration? The `rawExecSQL` is not supposed to return any values so which method should we use instead? Is the `public Cursor rawQuery(String sql, String[] selectionArgs, int initialRead, int maxRead)` a way to go? Should we throw some RuntimeException in `postKey` body to propagate the issue?

Best regards,  
Robert

---

<div class="post-metadata">

**Author:** ![robertszuba](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/robertszuba/32/1749_2.png) [@robertszuba](https://discuss.zetetic.net/u/robertszuba)\
**Post date:** [February 4, 2022, 9:52am UTC](https://discuss.zetetic.net/t/how-to-properly-use-sqlcipher-4-5-0-on-android/5262/2 "2022-02-04T09:52:09Z")

</div>

Are there no official recommendations on how to implement the migration?

---

<div class="post-metadata">

**Author:** ![developernotes](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/developernotes/32/1309_2.png) [@developernotes](https://discuss.zetetic.net/u/developernotes)\
**Post date:** [February 4, 2022, 6:24pm UTC](https://discuss.zetetic.net/t/how-to-properly-use-sqlcipher-4-5-0-on-android/5262/3 "2022-02-04T18:24:07Z")

</div>

Hi @robertszuba

My apologizes for the delayed response. When you execute `PRAGMA cipher_migrate`, you will want to check the return value (i.e., `0` is success). [Here](https://github.com/sqlcipher/sqlcipher-android-tests/blob/master/app/src/main/java/net/zetetic/tests/CipherMigrateTest.java#L24-L26) is an example within our Android test suite. In terms of how you should communicate a migration error state, that would be very application specific. We’ve shared general guidance for upgrading to the major version 4 of SQLCipher [here](https://discuss.zetetic.net/t/upgrading-to-sqlcipher-4/3283).
