Using Kotlin Extension Functions and Coroutines with Firebase
Tags: firebase, kotlin, android, ktx
Published: 2019-04-09 08:58:53

---
title: "Using Kotlin Extension Functions and Coroutines with Firebase"
published: true
description: "Take advantage of Kotlin Features when using Firebase"
tags: ["firebase", "kotlin", "android", "ktx"]
---

_Portuguese Version available on [developingwith.firebaseapp.com](https://developingwith.firebaseapp.com/Kotlin-Features-Firebase/)_

> "The simpler the code, the faster you'll understand it." - 
> [Paulo Enoque](https://medium.com/@pauloenoque2014)

Kotlin's simplicity and concision are the main reason why developers have been adopting this language for their work.
I must also remind you that, in May 2017, Google announced that Kotlin became an official language for Android App Development. Ever since then, the number of Kotlin developers has been increasing.

---

A year and a half after Kotlin became the official language for Android Development, Firebase added this language to their [official documentation](https://firebase.google.com/docs) :

<blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr"><a href="https://twitter.com/Firebase?ref_src=twsrc%5Etfw">@Firebase</a> code samples for Android are starting to get <a href="https://twitter.com/kotlin?ref_src=twsrc%5Etfw">@kotlin</a> samples to go with Java! Thanks to @daggerdwivedi and <a href="https://twitter.com/_rpfernandes?ref_src=twsrc%5Etfw">@_rpfernandes</a> for the assists here. It&#39;s a tremendous effort overall, and it&#39;s great to have help from the community.<a href="https://t.co/PMlAViMf9F">https://t.co/PMlAViMf9F</a><a href="https://twitter.com/hashtag/AndroidDev?src=hash&amp;ref_src=twsrc%5Etfw">#AndroidDev</a> <a href="https://t.co/W386VlM3HC">pic.twitter.com/W386VlM3HC</a></p>&mdash; Doug Stevenson 🔥 (@CodingDoug) <a href="https://twitter.com/CodingDoug/status/1050473809994629120?ref_src=twsrc%5Etfw">October 11, 2018</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

But I must agree with the popular saying "Better late than never". This change brought many improvements to the platform:
 - The Java code on the [Firebase Android SDK](https://github.com/firebase/firebase-android-sdk) was improved for better interoperability with Kotlin;
 - "Extension Functions" were created to make the use of the Android SDK more concise;
 - Some developers created libraries to improve the way Firebase is used with Kotlin, etc.

I  decided to create a library to help people use Firebase in Kotlin, it was called [fireXtensions](https://github.com/rosariopfernandes/fireXtensions) (now deprecated) and it used to provide some **Extension Functions** for the Firebase Android SDK.


# Kotlin Extension Functions

Putting it short, Extension Functions are a Kotlin feature that allows you to add new methods/functions to a class, even if this class was not created by you. No need to implement the class nor extend it.

After adding Kotlin to their Official Documentation, the Firebase Team has also added a few Extension Functions to their Android SDK (thus deprecating fireXtensions).

The first extensions were the libraries **Common KTX** and **Firestore KTX**.

## Common KTX

The `firebase-common-ktx` module contains extension functions used to obtain the Firebase Instance. If you've ever worked with Firebase (either in Java or Kotlin), you're probably familiarized with the method/function `FirebaseApp.getInstance()`. If you use the `firebase-common-ktx` module, calling this method gets easier: `Firebase.app`.

In order to use this module, make sure you have the Kotlin Plugin 1.3.20 or higher on your `build.gradle(project)` file:
 
```groovy
dependencies {
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.20"
}
```

And then add the following dependency to your `build.gradle(app)`:

```groovy
dependencies {
    // ... Other dependencies ...
    implementation 'com.google.firebase:firebase-common-ktx:16.1.0'
}
```

See the full list of [available extension functions](https://firebaseopensource.com/projects/firebase/firebase-android-sdk/docs/ktx/common.md/).

## Firestore KTX

As the name suggests, this module contains extensions that simplify the way you use the Firestore Android SDK. This module can be added to your project the same way we did with Common KTX, but using this dependency instead:

```groovy
dependencies {
    // ... Other dependencies ...
    implementation 'com.google.firebase:firebase-firestore-ktx:18.2.0'
}
```

See the full list of [available extension functions](https://firebaseopensource.com/projects/firebase/firebase-android-sdk/docs/ktx/firestore.md/).

Note that when using the `firebase-firestore-ktx` dependency, you no longer need to use `com.google.firebase:firebase-firestore`.

Although these are currently the only available modules, I'm pretty sure more modules will be added to their SDK. I'll update this post every time a new module is added.

# Kotlin Coroutines

As you might already know, [Firebase APIs are asynchronous](https://medium.com/google-developers/why-are-firebase-apis-asynchronous-callbacks-promises-tasks-e037a6654a93), forcing us to use listeners in our code to read data from our database. And programmers often try to (wrongly) read data without listeners, or try to use the data outside those listeners, like this:

**Example 1:** Read all users stored in Firestore.

```kotlin
// What we would like to do
// (PS: This code doesn't work)
val db = FirebaseFirestore.getInstance()
var users = db.collection("users").get()
updateUI(users)

// (This code doesn't work either)
// What some people do (wrongly)
var users: List<User>()? = null
usersRef.get().addOnSuccessListener { querySnapshot ->
    users = querySnapshot.toObjects(User::class.java)
}
if (users == null) {
    displayError()
    // displayError() will always be called because
    // the users list is loaded asynchronously.
    // The if is executed while the list hasn't been loaded yet.
} else {
    updateUI(users)
}



// What they should do:
usersRef.get()
    .addOnSuccessListener { querySnapshot ->
        val users = querySnapshot.toObjects(Userr::class.java)
        updateUI(users)
        // The method is now being called after
        // loading the users list.
    }.addOnFailureListener { e ->
        displayError()
    }
```

Looking at the code above, you might think there's nothing wrong with listeners, because everything makes sense and even keeps the code organized. But what if you need to read data from different collections and merge the results before displaying on the app UI? This would force us to use nested listeners, which is not so easy to read, as we can see bellow:


**Example 2:** Load John's profile and his list of friends (this list is stored under a different collection).

```kotlin
// Allow me to send a shot out to all
// JavaScript Developers who have been to callback hell
usersRef.document("john").get().addOnSuccessListener { querySnapshot ->
            val johnUser = querySnapshot.toObject(User::class.java)
                                                             
            friendsRef.get().addOnSuccessListener { friendSnapshot ->
                val friends = friendSnapshot.toObjects(Friend::class.java)
                showProfileAndFriends(johnUser, friends)
            }.addOnFailureListener {
                displayError()
            }
                                                             
        }.addOnFailureListener { e ->
            displayError()
        }
```


[Coroutines](https://kotlinlang.org/docs/reference/coroutines/coroutines-guide.html) have come to change that. They allow you to write asynchronous code as if it was synchronous, making it more concise and easier to read.
In order to use Coroutines in your Android Project, make sure you're using version 1.3.x or higher of the Kotlin Plugin, and then add the following dependencies to your build.gradle(app) file:
```groovy
dependencies {
    // ... Other Dependencies ...
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1'
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.1.1'
}
```

As of the time this was posted, 1.1.1 was the latest version. You can check the [maven repository](https://mvnrepository.com/artifact/org.jetbrains.kotlinx/kotlinx-coroutines-play-services) for the latest version of kotlinx-coroutines-play-services.

Now, if we used Coroutines in our **first example**, it would become:
```kotlin
try {
    val snapshot = usersRef.get().await()
    val users = snapshot.toObjects(User::class.java)
    updateUI(users)
} catch (e: FirebaseFirestoreException) {
    displayError()
}
```

It resembles our "What we would like to do" code from example 1, doesn't it?

Now our **second example**:
```kotlin
try {
    val querySnapshot = usersRef.document("john").get().await()
    val johnUser = querySnapshot.toObject(User::class.java)
    
    val friendSnapshot = friendsRef.get().await()
    val friends = friendSnapshot.toObjects(Friend::class.java)
    showProfileAndFriends(johnUser, friends)
} catch (e: FirebaseFirestoreException) {
    displayError()
}
```

The code now looks synchronous and easier to read, right?

---

And that's all. I hope you found these Kotlin features useful and I hope that they'll improve your productivity when developing firebase apps.



If you have any doubts or suggestions, please leave it on the comments bellow.

If you're trying to use the Kotlin Extensions or Coroutines and ran into a problem, you can post it on [StackOverflow](https://pt.stackoverflow.com/questions/ask?tags=firebase) explaining what you did and what error you ran into. I'm sure you'll find help (either from me or someone from the Firebase Community).