'How to combine local and remote data source in repository?

I currently get data from the local data source (local SQLite DB) and check if it is empty.
If it is empty, I fetch data from the remote.

Current code

class EmojiRepositoryImpl(
    private val emojiDao: EmojiDao,
) : EmojiRepository {
    override val emojis: Flow<List<Emoji>> = emojiDao.getEmojis()
            .map {
                it.ifEmpty {
                    getEmojisDataFromRemote()
                }
            }

    private suspend fun getEmojisDataFromRemote(): List<Emoji> {
        return EmojiApi
            .retrofitService
            .getEmojis(
                accessKey = BuildConfig.OPEN_EMOJI_KEY,
            )
    }
}

Now, I am trying to make the local database the single source of truth.

To achieve that, getEmojisDataFromRemote becomes

private suspend fun saveEmojisDataFromRemote() {
    val data = EmojiApi
        .retrofitService
        .getEmojis(
            accessKey = BuildConfig.OPEN_EMOJI_KEY,
        )
    saveToDatabse(data)
}

And the data retrieval will be,

override val emojis: Flow<List<Emoji>> = emojiDao.getEmojis()

Now, how to call this saveEmojisDataFromRemote() when there is no data in the local database so that it fetches the data from the remote source and updates the local DB?

What I had tried,

init {
    runBlocking(
        context = Dispatchers.IO,
    ) {
        emojis.collect {
            if (it.isEmpty()) {
                saveEmojisDataFromRemote()
            }
        }
    }
}

Problems with this code,

  1. It is not working, 😔
  2. Trying to avoid runBlocking usage if possible.


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source