Get data from Firestore where an array match a list of data in Kotlin

Viewed 666

Following is the structure of my Firestore database. I want to get all the documents from the collection 'products' where the 'pin_code' (is an Array) matches with the list of pin codes I have. The list of pin codes is from the collection 'addresses' which I have managed to get with the following code. But I am not able to get documents from the collection 'products' that match the list of pin codes.

Following is the code I have to get the pin code list from the collection 'addresses'

        fun getPins(context: DashboardFragment) {

        mFireStore.collection("addresses")
            .whereEqualTo("user_id", getCurrentUserID())
            .get()
            .addOnSuccessListener { document ->

                val codeList: MutableList<String> = mutableListOf()

                for (i in document.documents) {

                    val code = i.toObject(Address::class.java)
                    code!!.user_id = i.id

                    codeList.add(code.pinCode)

                }

                context.getProductListBasedOnPin(codeList)

            }
            .addOnFailureListener { e ->

            }

    }

I tried to get the data from the collection 'products' with the following code. But with this code I can get the list of products only when my 'pin_code' is not an array. But I had to make the pin_code an array for some reason and I am not able to get the product list.

    fun getProductListBasedOnPin(pinList: List<String>?) {
    val mFireStore = FirebaseFirestore.getInstance()

    mFireStore.collection("products")
        .whereIn("pin_code", pinList!!)
        .get()
        .addOnSuccessListener { document ->

            for (i in document.documents) {

                val product = i.toObject(Product::class.java)!!
                product.product_id = i.id
                srchProductsList.add(product)

            }

            srchTempProductsList.addAll(srchProductsList)

            if (newView == "ListView") {

                successDashboardItemsListListView(srchTempProductsList)
            } else {
                successDashboardItemsList(srchTempProductsList)
            }

        }
        .addOnFailureListener {

        }
}

Can someone help me with this?

Thank you.

enter image description here

2 Answers

I want to get all the documents from the collection 'products' where the 'pin_code' (is an Array) matches with the list of pin codes I have.

You can definitely do that using Query's whereArrayContainsAny(String field, List<? extends Object> values) method, which:

Creates and returns a new Query with the additional filter that documents must contain the specified field, the value must be an array, and that the array must contain at least one value from the provided list.

Assuming that you want to get all documents from the "products" collection in which the "pin_code" arrays contains a List with two values ("123456" and "159874"), please use the following lines of code:

val pinCodeList = listOf("123456", "159874")
productsRef.whereArrayContainsAny("pin_code", pinCodeList).get().addOnCompleteListener {
    if (it.isSuccessful) {
        for (document in it.result) {
            Log.d(TAG, document.id + " => " + document.data)
        }
    } else {
        Log.d(TAG, "Error getting documents: ", task.exception)
    }
}

This is done using an Array Contains conditions, using one of the various methods, you can see if an array contains some, any, all, and not-in.

val citiesRef = db.collection("products")

citiesRef.whereIn("pin_code", listOf("123456", "150875"))

Once you fetch this snapshot, it will return an array of matching documents which you can then use with other sections of your app logic and secondary Firestore queries as needed.

Source: https://firebase.google.com/docs/firestore/query-data/queries#kotlin+ktx_6

Related