본문 바로가기
오늘은 뭘 배울까?/Android

앱을 삭제했는데 데이터가 남아있어요 + Room cannot verify the data integrity.

by Kim Juhwan 2021. 3. 13.

0. 프롤로그(TMI)
1. 앱을 삭제했는데 데이터가 남아 있다구요?
2. Room cannot verify the data integrity.
   2-1. 난 기존 데이터 따위는 날아가도 상관없다.
   2-2. 안 돼!!! 데이터 날아가면 안 돼!!!
   2-3. 중복된 이름을 사용하는 경우

 

 


 

0. 프롤로그(TMI)

@Dao
interface TodoDao {
    @Query("SELECT * FROM Todo")
    fun getAll(): List<Todo>

    ...
}

기존에 내가 앱에서 사용하면 Dao는 이렇게 List를 저장하고 불러오는 형식이었다.

근데 이번에 LiveData에 대해 배우면서 전면 수정하려고 하는데

 

@Dao
interface TodoDao {
    @Query("SELECT * FROM Todo")
    fun getAll(): LiveData<List<Todo>>

    ...
}

만약 내가 LiveData로 기존의 데이터를 감싸면..?

내가 DB 테이블을 수정한 것처럼 되려나..?

그러면 version을 증가시키거나 migration을 해야 하나??

그러면 기존 사용자들이 가지고 있던 데이터는 어떻게 하지 날아가면 안 되는데..

이런 고민들을 했는데 결론은 테이블에 저장되는 건 그대로 List이고 불러오고 나서 LiveData로 감싸주는 거라서 아무 지장이 없다.

 

암튼 이걸 알아보기 위해서 이것저것 하다가 삽질을 엄청 했는데

새로 알게 된 사실이 있어서 기록하려 한다.

 

1. 앱을 삭제했는데 데이터가 남아 있다구요?

...

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"

...

Manifests 파일의 일부분이다.

여기서 allowBackup의 디폴트 값이 true로 되어있을 텐데 이게 진짜 어이없고 이해가 안 가는 부분이다.

이게 true로 되어있으면 앱을 삭제하거나 설정에 들어가서 데이터/캐시 지우기해도 데이터베이스가 살아있다.

안드로이드 6.0부터는 앱을 삭제해도 구글 드라이브에 데이터베이스를 백업해둔다고 한다.

나는 그것도 모르고 계속 DB가 꼬이고 쌓이고 난리 부르스를 쳐서.. 하...

 

공식문서에서 이 사실을 확인할 수 있다.

 

2. Room cannot verify the data integrity.

Looks like you've changed schema but forgot to update the version number. You can simply fix this by increasing the version number.

이 에러가 계속 떠서 미쳐버리는 줄 알았다.

데이터의 무결성을 위반해서 뜨는 에러인데 버전을 올려서 해결하라고 나와있다.

좀 더 쉽게 표현하면 이런 것이다.

"엥? 야 너 이 이름으로 데이터베이스 이미 만들었잖아. 테이블 내용을 바꾸려고?"

"그러면 버전 올려~ 간단하게 해결할 수 있어"

여기서 저 말에 현혹되지 말고 상황에 맞게 해결해야 한다.

 

2-1. 난 기존 데이터 따위는 날아가도 상관없다.

        var db = Room.databaseBuilder(
                application,
                TestDatabase::class.java, "database-test"
        )
                .fallbackToDestructiveMigration() // 기존 데이터를 버리고 다음 버전으로 넘어감
                .build()

build 할 때 fallbackToDestructiveMigration()를 호출해서 기존 데이터를 버리고

 

@Database(entities = [Test::class], version = 1, exportSchema = false)
abstract class TestDatabase: RoomDatabase() {
    abstract fun testDao(): TestDao
}

버전을 올려주면 된다. 예를 들어 위의 코드 경우 version이 1로 되어있으니 2로 바꾸어주면 된다.

 

2-2. 안 돼!!! 데이터 날아가면 안 돼!!!

내 소듕한 데이터...

이미 출시한 앱의 경우 사용자들이 저장해둔 데이터가 삭제되면 안 되니 migration을 해야 한다.

이 경우 [목차 2-1]에서 설명한 fallbackToDestructiveMigration을 절대절대절대절대 쓰면 안 된다.

나는 여기에 해당되지 않아서 방법만 찾아보고 시도를 해보지 않았기 때문에 잘 설명되어 있는 링크만 몇 개 첨부하려고 한다.

 

 

2-3. 중복된 이름을 사용하는 경우

        var db = Room.databaseBuilder(
                application,
                TestDatabase::class.java, "database-test" // 이름 중복 확인
        )
                .build()

혹시 앱에서 데이터베이스를 쓰는 곳이 여러 군데라면 이름이 중복되진 않는지 확인해보자

나는 기존 코드를 복붙 하는 과정에서 이름 바꾸는 걸 까먹어서 계속 이 에러가 떴다. 진짜 멍청...

 

 


💡 느낀 점

  • 굳이 앱의 데이터를 구글 드라이브에 백업하는 이유는 무엇일까? 심지어 디폴트 값도 true이다.
  • 이것 때문에 보안 취약 점이 생긴다고 하니 꼭 필요한 게 아니라면 항상 false로 바꿔야겠다.
  • Room에 대해 설명하는 블로그는 많아도 migration까지 다루는 블로그는 많지 않다. 공부해서 올려야겠다.
  • 어이없는 실수로 반나절을 날렸더니 현타가...

반응형

댓글