Build better apps, faster

Firebase with Jetpack Compose — Cloud Firestore

Pankaj Rai 🇮🇳
Firebase Developers
3 min readMar 11, 2021

--

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 calling awaitClose 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 method getBookDetails() , which will return a Flow of BooksResponse.

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 call
collectAsState() 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 the MutableStateFlow object inside it. The reason for this is to set updated data fetched from the BooksRepo to the MutableStateFlow 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 the MutableStateFlow 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.

Resources

--

--

Pankaj Rai 🇮🇳
Firebase Developers

Software Engineer | GDE Android & Firebase | YouTuber — All Techies