Case study · Logistics
Real-time delivery tracking for drivers
A mission-critical driver app that streams delivery updates in real time with Firestore, Coroutines and Flow, made testable with Koin.
- Role
- Android Engineer
- Company
- T10
- Period
- Aug 2022 – Feb 2023
Context
T10 works in logistics. From August 2022 to February 2023 I developed and maintained its delivery driver app, a mission-critical tool: when it stops working, deliveries stop too. The app is built with Kotlin, MVVM and Firebase Firestore.
Challenge
- Real time, all the time. Delivery data changes constantly, and drivers need to see each update as soon as it happens.
- No leaks, no frozen screens. Firestore listeners have to start and stop with the screen, and updates must reach the UI without blocking the main thread.
- Confidence to change. A mission-critical app needs code that can be tested in isolation, which means dependencies that can be swapped.
Approach
Reactive streams with Coroutines and Flow. I wrapped Firestore snapshot listeners in callbackFlow, turning callbacks into cold flows. The listener is registered when the UI starts collecting and removed in awaitClose when it stops, so there is nothing to forget to unregister.
fun observeDelivery(id: String): Flow<Delivery> = callbackFlow {
val registration = firestore
.collection("deliveries")
.document(id)
.addSnapshotListener { snapshot, error ->
if (error != null) {
close(error)
return@addSnapshotListener
}
snapshot?.toObject<Delivery>()?.let { trySend(it) }
}
awaitClose { registration.remove() }
}State that outlives rotations. Repositories expose flows, and ViewModels turn them into StateFlow with stateIn. The UI always renders the latest known state, and a configuration change doesn’t restart the stream.
Dependency injection with Koin. I integrated Koin to declare dependencies in modules. Swapping Firestore-backed implementations for fakes in tests became trivial, and the modular architecture became more stable.
Architecture
Results
- Real-time delivery tracking powered by reactive streams with Coroutines, Flow and Firestore.
- Listeners tied to the UI lifecycle, so updates stop as soon as nobody is watching.
- Better testability and a more stable modular architecture with Koin.
Stack
The tools behind this work, all used in production:
- Kotlin
- MVVM
- Firebase Firestore
- Coroutines
- Flow
- Koin
Details are simplified and client names are omitted to respect confidentiality.
Next case study
Pix payments at superapp scale
Zup InnovationWant to build something like this?
I’m open to senior Android roles at international companies.