Is there an existing issue?
Use case
I'm writing a non-custodial cryptocurrency wallet app for Android. I have the next structure:
- Vaults (seed phrases)
|-> Wallets (derived from seed phrases or imported private keys)
So, I modelled 2 entities:
1- VaultEntity
@Entity
data class VaultEntity(
@Id
var id: Long? = null,
...
) {
@Backlink(to = "vault")
lateinit var wallets: ToMany<WalletEntity>
}
2- WalletEntity
@Entity
data class WalletEntity(
@Id
var id: Long? = null,
...
) {
lateinit var vault: ToOne<VaultEntity>
}
Then, I observe the table with the relation in the user interface getting the flow from a subscription to a query:
[UI]
@Composable
fun WalletsLayout() {
val appContainer = LocalAppContainer.current
val vaultsWithWallets by appContainer.vaultsViewModel.vaultsWithWalletsFlow.collectAsState()
LazyColumn {
itemsIndexed(vaultsWithWallets) { vaultIndex, vaultWithWallets ->
...
vaultWithWallets.wallets.forEachIndexed { walletIndex, wallet ->
....
}
}
}
}
[View model]
class VaultsViewModel(private val repository: VaultsRepository) : ViewModel() {
// Here, I create a single point of monitorization that several observers in the UI can use. So, only one query().subscribe() for all
val vaultsWithWalletsFlow = repository.vaultsWithWalletsFlow.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5000),
initialValue = emptyList()
)
}
[Repository]
class VaultsRepository(boxStore: BoxStore) {
private val dispatcher = boxStore.newCachedThreadPoolDispatcher()
private val box = boxStore.boxFor(VaultEntity::class)
// Instead of using .observer { data -> onUpdate(data) }, I use the conveniente convertion to Flow because it is more natural to the UI and is the way Android proposes to monitorize the tables using Room
val vaultsWithWalletsFlow =
box.query().order(VaultEntity_.name).eager(VaultEntity_.wallets).build()
.subscribe().toFlow()
suspend fun createSeedPhraseVault(
name: String
) = try {
val insertedId = withContext(dispatcher) {
box.put(
VaultEntity(
type = VaultType.SEED_PHRASE.ordinal,
name = name.toString(Charsets.UTF_8),
)
)
}
Result.success(insertedId)
} catch (e: Exception) {
Result.failure(e)
}
}
class WalletsRepository(
private val context: Context,
boxStore: BoxStore
) {
private val dispatcher = boxStore.newCachedThreadPoolDispatcher()
private val box = boxStore.boxFor(WalletEntity::class)
suspend fun deriveWallet(
vault: VaultEntity,
name: String
) = try {
withContext(dispatcher) {
vault.wallets.reset()
vault.wallets.add(
WalletEntity(
name = name
)
)
vault.wallets.applyChangesToDb()
}
Result.success(true)
} catch (e: Exception) {
Result.failure(e)
}
}
The issue resides in the values of the relation that doesn't get notified to the observers when I modified them (add a new wallet to a vault) in another UI screen, so when I return from the wallet screen creation to the vaults and wallets screen, i cannot see the recently created wallet in the list.
I imagine that this relation thing works similar to an SQL SELECT LEFT JOIN. I suppose that this should be the behavior, but it is not. As a note, Room does notify when the relation table changed.
Proposed solution
Implement the monitorization of the main table and all the relations. If I declare them and use them in the query is because they are important.
Alternatives
Maybe add a function that trigger the recomposition of the flow.
Additional context
Is there an existing issue?
There is no other opened issue related to this
Use case
I'm writing a non-custodial cryptocurrency wallet app for Android. I have the next structure:
|-> Wallets (derived from seed phrases or imported private keys)
So, I modelled 2 entities:
1- VaultEntity
2- WalletEntity
Then, I observe the table with the relation in the user interface getting the flow from a subscription to a query:
[UI]
[View model]
[Repository]
The issue resides in the values of the relation that doesn't get notified to the observers when I modified them (add a new wallet to a vault) in another UI screen, so when I return from the wallet screen creation to the vaults and wallets screen, i cannot see the recently created wallet in the list.
I imagine that this relation thing works similar to an SQL SELECT LEFT JOIN. I suppose that this should be the behavior, but it is not. As a note, Room does notify when the relation table changed.
Proposed solution
Implement the monitorization of the main table and all the relations. If I declare them and use them in the query is because they are important.
Alternatives
Maybe add a function that trigger the recomposition of the flow.
Additional context