Why Android Datastore always returns same value with runblocking

Viewed 734

I've been using Datastore for a long time. Today i had to read the values in the main thread. After reviewing the documentation, I decided to use runblocking. I created a long value which name is lastInsertedId.

I reading lastInsertedId in Fragment A then navigated to Fragment B and I'm changing the value of lastInsertedId. When i pop back to Fragment A i read lastInsertedId again. But lastInsertedId's value was still same. Actually it's value is changing but i can't read its last value.

I think it was because Fragment A was not destroyed. Only onDestroyView called and created from onCreateView. What i want is i need to access lastInsertedID's current value whenever i want in main thread.

When i create it as a variable, it always returns the same value. But when i convert it to function it works well. But i don't think this is the best practices. What's the best way to access this value? Thanks.

private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "main")

@Singleton
class DataStoreManager @Inject constructor(@ApplicationContext appContext: Context) {

    private val mainDataStore = appContext.dataStore

    suspend fun setLastInsertedId(lastId: Long) {
        mainDataStore.edit { main ->
            main[LAST_INSERTED_ID] = lastId
        }
    }

    // Returns always the same value
    val lastInsertedId: Long = runBlocking {
        mainDataStore.data.map { preferences ->
            preferences[LAST_INSERTED_ID] ?: 0
        }.first()
    }

    // Returns as expected
    fun lastInsertedId(): Long = runBlocking {
        mainDataStore.data.map { preferences ->
            preferences[LAST_INSERTED_ID] ?: 0
        }.first()
    }

    // This is also work perfectly but i need to access in main thread.
    val lastInsertedId : Flow<Long> =  mainDataStore.data.map { preferences ->
        preferences[LAST_INSERTED_ID] ?: Constants.DEFAULT_FOOD_ID
    }

    companion object {
        private val LAST_INSERTED_ID = longPreferencesKey("last_inserted_id")
    }
}
2 Answers

You must add get() to your val definition like this.

val lastInsertedId: Long get() = runBlocking {
    mainDataStore.data.map { preferences ->
        preferences[LAST_INSERTED_ID] ?: 0
    }.first()
}

You seems don't understand the differece between variable and function, take a look at this:

fun main() {
    val randomNum1 = (1..10).random()

    repeat(5) { println(randomNum1) }
    repeat(5) { println(getRandomNum()) }
}

fun getRandomNum() = (1..10).random()

Output:

2
2
2
2
2
8
7
8
10
1

Variable holds a value, and it doesn't change until you assign it a new value.

Related