Build better apps, faster
Firebase with Jetpack Compose — Cloud Firestore
Jetpack Compose is the next-generation Android UI toolkit that helps to create UIs with very little effort.
Apart from UI components, it also provides a kind of observer pattern out of the box. In Jetpack Compose, this is called State. Whenever the State changes, the composable will be recomposed. This means the UI gets updated with the new state which could be a change of text, color, shape, size, etc.
So if Jetpack Compose makes it more efficient to build UIs, and Firebase makes it more efficient to build apps, how about we bring both together to leverage their combined power?
Updating the existing Cloud Firestore APIs
Cloud Firestore SDK for Android comes in two flavours: Java Android and Kotlin+KTX Android, and both provide a callback-based mechanism to read or write data. However, for Jetpack Compose, an observer-based mechanism works better than a callback-driven approach.
Kotlin Flow or LiveData?
You can use either Kotlin Flow or LiveData to implement an observer pattern, but in this article, I am going to show how to use Kotlin Flow to do this. In fact, I would recommend migrating from LiveData to Kotlin Flow as it is much more flexible.
So let’s create the BooksRepo
and add a method to read the data in realtime using the existing snapshot API.
As you can see we are using
callbackFlow
which is the Flow builder that acts on callback-based APIs whose subscription has to be removed at a later point in time. Here we are callingawaitClose
which will get triggered as soon as this Flow is no longer active/observed/subscribed.
So far we transformed the callback-based API to an observer-based one. Now let's take a look at our ViewModel which will supply the fetched data from Cloud Firestore to the composable.
BooksViewModel
There are two approaches: one is to pass data emitted from the Flow builder directly to the composable using the ViewModel object. Another is to create an instance of MutableStateFlow
which will be observed in the composable. An important thing to notice here is that in case you go ahead with the second approach then do remember to call the collect()
method inside the BooksViewModel
that opens up the subscription so that when data is emitted from the Flow builder it will be collected in realtime.
Approach One — Using a ViewModel
In this approach, let's see how we can read data from the ViewModel without creating a MutableStateFlow
object.
In this
BooksViewModel
, we are just calling the methodgetBookDetails()
, which will return a Flow ofBooksResponse
.
Now let’s see the book details fetched from the repository by creating our UI with Jetpack Compose.
The important thing to notice here is on line number 19:
booksViewModel.getBooksInfo().collectAsState(initial = null).value
It’s really important to callcollectAsState()
with some initial value otherwise it will not able to recompose the composable.
Approach Two — Using MutableStateFlow
In this approach, we will create a MutableStateFlow
object in our ViewModel that will be used to observe data in our composable.
It’s important to call the
collect()
method and set theMutableStateFlow
object inside it. The reason for this is to set updated data fetched from theBooksRepo
to theMutableStateFlow
object.
Now let’s see how to change the composable:
As you can see in line number 5 the important method here is the
collectAsState()
method so that when new data is set to theMutableStateFlow
object inside ViewModel it will automatically recompose this composable.
Conclusion
So with just a couple of steps, we were able to add Cloud Firestore to an Android app based on Jetpack Compose.