Skip to content

Instantly share code, notes, and snippets.

@crazyhitty
Last active March 18, 2020 18:31
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save crazyhitty/950b52a7c1bb5ddeaba1814e20aeab6e to your computer and use it in GitHub Desktop.
Save crazyhitty/950b52a7c1bb5ddeaba1814e20aeab6e to your computer and use it in GitHub Desktop.
Issues with RxRoom and Flowable

In RxRoom, Flowable will always emit atleast one item, so using single() and isEmpty() functions won't work as expected.

So, the one where you are checking if projects are cached or not using isEmpty() function, room will still emit one item which would be an empty list object. This happens because even if no values exist in db, Room will still create an empty list first and then try to populate it if any items exist. Finally, it would emit the list object even if it is empty.

You can resolve this issue by updating the areProjectsCached() function in ProjectsCacheImpl.kt like this:

override fun areProjectsCached(): Single<Boolean> =
    projectsDatabase.cachedProjectsDao()
        .getProjects()
        .first(emptyList())
        .map { !it.isEmpty() }

Also, in case of expiration check, you are converting Flowable to Single using single(defaultItem) function. Here, RxRoom will check if any data is there or not for that query and if there is no data it would return null. Then, it would filter out the null values internally as RxJava isn't cool with null values. And eventually they will still emit an empty object ,i.e., new Object() even if there is no data to emit. Thus, even if we pass defaultItem to single(defaultItem) function, it won't accept that defaultItem as the Flowable would already have java's Object instance as an existing item. So, if you don't save any data in config table before accessing it, it won't use the defaultItem and would fail.

This can be resolved if you use Maybe instead of using Flowable for getting the config as RxRoom doesn't modifies the creation of Maybe internally like it does in case of Flowable.

So, in ConfigDao.kt, update getConfig() function to return Config wrapped inside a Maybe like this:

abstract fun getConfig(): Maybe<Config>

Also, change the isProjectsCacheExpired() function in ProjectsCacheImpl.kt like this:

projectsDatabase.configDao()
          .getConfig()
          .toSingle(Config(lastCacheTime = 0L))
          .map {
            System.currentTimeMillis() - it.lastCacheTime > (60 * 10 * 1000).toLong()
          }

This might resolve the issues people are facing in this thread regarding the failure of expiration tests.

NOTE: You can also check createFlowable method in RxRoom.java on how it is created internally.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment