How to write a method in Kotlin that will return a string from Firestore?

Viewed 209

This is not a duplicate and the suggested link is for JAVA but I am looking for Kotlin

I wanted to write a method that will return the value of a particular field of a document in Firestore. I know how to get the value but I am not able to return the value.

This is what I have.

    fun getCurrentUserType(): String {
    var userType = ""
    mFireStore.collection("users")
        .document(getCurrentUserID())
        .get()
        .addOnSuccessListener { document ->
            val usrType: String? = document.getString("user_type")
            if (usrType != null) {
                userType = usrType
            }

        }
    return userType
}

As you know, this return statement executes before getting the data from the Firestore, so it's of no use.

As I read on Stackoverflow, the return method has to be in an addOnCompleteListener. I cannot call addOnCompleteListener in the above code that I have and I tried doing it as follows but that doesn't work. Can you help, please?

I get the correct value in the Logcat though using the following code.

Following is how tried.

    fun getCurrentUserType(): String {

    mFireStore.collection("users").get().addOnCompleteListener { task ->
        if (task.isSuccessful) {
            val list = ArrayList<String>()
            for (document in task.result) {
                val userType = document.data["user_type"].toString()
                list.add(userType)
            }
            Log.d("UserType is ", list[0])
            val userTye = list[0]
            return@addOnCompleteListener userTye
        }
    }

}
2 Answers

I know how to get the value but I am not able to return the value.

As you already noticed, you can read the value of a field but you cannot return it, and it makes sense since the Firebase API is asynchronous. Meaning, that any code that needs data from Firestore, needs to be inside the onComplete() method, or be called from there.

In short, there is no way you can return the userType object as a result of a method unless you don't have a special mechanism for that. This is happening because it takes some time until the data is finished loading.

I recently wrote an article called:

In which I have explained four ways in which you can interact with Firestore using:

  1. Callback
  2. Android Architecture Components -> ViewModel + LiveData
  3. Kotlin Coroutines
  4. Asynchronous Flow

Since you are looking in your question for a way to return the data from the database call, the last three solutions will help you achieve that. Remember, that these ways of handling asynchronous programming are recommended by the Android team.

doc.data() is an object, you can get field data just like you would get any other object's field data.

 mFireStore.collection("users").get().then((doc) => {
    if (doc.exists) {
        let data = doc.data()
        let yourField = data.yourFieldsName
    } else {
        // doc.data() will be undefined in this case
        console.log("No such document!");
    }
Related