Search code examples
androidfirebasekotlinkotlin-coroutineskotlin-flow

Detect when all flows produced value


I''m having two functions which upload some data to database.

suspend fun addOverallRatingValue(productId: String): Flow<FirebaseEventResponse>
suspend fun markProductAsRatedByUser(productId: String): Flow<FirebaseEventResponse>

Both of them are callbackFlow

override suspend fun markProductAsRatedByUser(productId: String) = callbackFlow {
        try {
            firebaseInstance
                ...
                .addOnSuccessListener {
                    trySend(FirebaseEventResponse.SuccessSetValue)
                }
                .addOnFailureListener {
                    trySend(FirebaseEventResponse.ExceptionOccurred.Event(it))
                }
        } catch (e: Exception) {
            trySend(FirebaseEventResponse.ExceptionOccurred.Event(e))
        }
        awaitClose { this.cancel() }
    }

How can I combine these two flows and react when both of them send any FirebaseEventResponse?


Solution

  • There are combine and zip functions you can use to combine flows:

    combine(
        flow1,
        flow2,
    ) { result1, result2 ->
        // ... check results
    }.launchIn(viewModelScope)
    

    The difference between them is that combine fires when the most recent value is emitted by each flow, and zip fires when each pair of value is emitted. Here is a good article about Flow operators.

    There is also merge function which merges the given flows into a single flow without preserving an order of elements:

    merge(flow1, flow2).onEach { result ->
        // ... use result
    }.launchIn(viewModelScope)