Reactive UI State
Anything Compose or SwiftUI should re-render on when it changes — a document's
flow() gives a UI layer exactly that, with no manual re-reads and no polling.
@Serializable
data class DownloadState(
val bytesDownloaded: Long = 0,
val totalBytes: Long = 0,
val isComplete: Boolean = false,
)
val download = Documents.document<DownloadState>("active-download")
A background worker updates bytesDownloaded as chunks arrive. It's a single field,
so update(prop, value) is the natural fit — one direct write to that key:
download.update(DownloadState::bytesDownloaded, bytesSoFar)
A Compose screen collects the same document and redraws on every write, with zero coupling to where the write came from:
@Composable
fun DownloadProgressBar(download: Document<DownloadState>) {
val state by download.flow().collectAsStateWithLifecycle(initialValue = download.get())
val progress = state?.let { it.bytesDownloaded.toFloat() / it.totalBytes } ?: 0f
LinearProgressIndicator(progress = progress)
}
The real sample app demonstrates this exact pattern end to end —
a button press writes to a document, and a separate readout re-renders purely by collecting its
flow(). See Reactivity for the full
flow()/stateFlow() API.