I’m experimenting with Room and Coroutines Flow observables in a simple project, but I’m encountering an issue where the Flow emits multiple times.
In the app, I’m fetching all data from the user’s fixed expenses table (like a monthly streaming service, cable TV, etc.) and observing the Flow in my ViewModel. The DAO returns Flow<List<FixedExpense>>
.
In the ViewModel, I’m collecting the Flow inside the ViewModel scope. Inside the collect block, I check if the payment date is expired. If it is, I add a new expense to the Expense table and update the last payment date of the fixed expenses to prevent paying the same expense again in the next check. (There is no issue in the check; I made unit tests before and it worked fine without data persistence with Room).
private fun observeFixedTransaction() {
viewModelScope.launch {
fixedExpenseRepository.fetchAll()
.distinctUntilChanged()
.collectLatest{
checkDueTransactions(it)
}
}
}
The problem is that when I add a new fixed expense or start collecting the Flow, it emits multiple times. This results in the check running multiple times, causing a race condition that adds multiple expenses. For some reason, a semaphore inside the collect block doesn’t work.
Why does the Flow emit more than once when I add a new row or start collecting the Flow?
I tried using debounce as well, but it didn’t work.
I tried using the debounce, but unless i set the timemilis to something like 10 seconds, it won’t work. Also tried to use a semaphore with tryattach but the collect block ignored the semaphore (it was initilizided inside the viewModel class).
Ranpu is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.