Skip to content

Instantly share code, notes, and snippets.

@bmc08gt
Created August 12, 2020 16:13
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 bmc08gt/ebc7b217f14acf47e8a4d953ef1a882c to your computer and use it in GitHub Desktop.
Save bmc08gt/ebc7b217f14acf47e8a4d953ef1a882c to your computer and use it in GitHub Desktop.
Firebase Real-time Database value event listener via Kotlin callbackFlow{} updating Jetpack Compose list
data class SnapshotResult(val snapshot: DataSnapshot? = null, val error: Throwable? = null)
fun DatabaseReference.listen(): Flow<SnapshotResult> =
callbackFlow {
val valueListener = object : ValueEventListener {
override fun onCancelled(databaseError: DatabaseError) {
close(databaseError.toException())
}
override fun onDataChange(snapshot: DataSnapshot) {
offer(SnapshotResult(snapshot, null))
}
}
addValueEventListener(valueListener)
awaitClose { removeEventListener(valueListener) }
}
fun locationsFlowable(): Flow<PantryResult<List<ItemLocation>>> {
return getLocationsChange()
}
fun getLocationsChange(): Flow<PantryResult<List<ItemLocation>>> {
val user = user() ?: return flow { PantryResult<List<ItemLocation>>(exception = UserNotAvailableException()) }
val ref = database.child("locations").child(user.uid)
return ref.listen().map {
val (data, error) = it
if (error != null) {
PantryResult(exception = error)
} else {
val locations = data?.children?.mapNotNull { child ->
child.getValue(ItemLocation::class.java)
} ?: emptyList()
PantryResult(locations)
}
}
}
@Composable
fun LocationsContent(
navigateTo: (Screen) -> Unit,
innerPadding: InnerPadding,
pantry: Pantry
) {
val result = pantry.locationsFlowable().collectAsState(initial = PantryResult(emptyList()))
if (result.value.isSuccess) {
if (result.value.data.isNullOrEmpty()) {
EmptyLocations()
} else {
LazyColumnFor(
modifier = Modifier.padding(innerPadding),
items = result.value.data.orEmpty()
) { location ->
Row(modifier = Modifier.padding(8.dp)) {
Text(text = location.label, style = MaterialTheme.typography.h3)
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment