https://kotlinlang.org logo
Title
a

Abhishek Dewan

03/12/2021, 5:39 AM
I am working on a KMM project where I have the following class
@ExperimentalTime
internal class AuthenticationRepositoryImpl(
    private val authenticationApi: AuthenticationApi,
    private val authenticationQueries: AuthenticationQueries
) : AuthenticationRepository {

    override suspend fun authenticateUser() {
        authenticationQueries.clearAuthenticationData()
        authenticationApi.authenticateUser().toAuthentication().apply {
            authenticationQueries.setAuthenticationData(accessToken, expiresBy)
        }
    }

    @ExperimentalTime
    override suspend fun getAuthenticationData(): Flow<Authentication?> {
        val timeNow = Clock.System.now().epochSeconds
        return authenticationQueries.getAuthenticationData(timeNow).asFlow().mapToOneOrNull()
    }
}
and I am calling the functions from my android app like so:
fun checkAuthentication() {
    viewModelScope.launch {
        authenticationRepository.getAuthenticationData().onEach {
            if (it != null) {
                Timber.d("Valid Authentication Found")
                isAuthenticationValid.value = true
            } else {
                Timber.d("Valid Authentication Not Found - Requesting Authentication")
                authenticationRepository.authenticateUser()
            }
        }.collect()
    }
}
In the following code if the authentication data is not present in the SqlDelight DB, I get a null in the onEach of the flow and then I trigger a fetch and save to DB. However, the save to DB does not re-trigger a flow update. Is there something I am doing wrong here?
If it helps here the sq file
CREATE TABLE Authentication(
accessToken TEXT NOT NULL UNIQUE,
expiresBy INTEGER NOT NULL
);

getAuthenticationData:
SELECT * FROM Authentication
WHERE expiresBy > ?;

setAuthenticationData:
INSERT INTO Authentication(accessToken, expiresBy)
VALUES (?,?);

clearAuthenticationData:
DELETE FROM Authentication;
Did some debugging and found that in my generated AppDbImpl class the setAuthenticationData is passing an empty
database.authenticationQueries.getAuthenticationData
not sure why thought
As can be seen in the screen recording when I call getAuthenticationData on my repository it should call the asFlow() extension to add the listener to the query and hence reflow future updates. But it seems like that collect and setting of the data is happening before I can get the asFlows to add the listener which then prevents my app from getting an updated value. Does anyone know what might be wrong?
Just for anyone who’s reading this later, the fix was to add a flowOn on the chain. It seems like the asFlow() and collect() was happening on two different threads.