【问题标题】:Get data from Firestore where an array match a list of data in Kotlin从 Firestore 获取数据,其中数组与 Kotlin 中的数据列表匹配
【发布时间】:2021-07-27 23:23:11
【问题描述】:

以下是我的Firestore 数据库的结构。我想从集合'products'中获取所有文档,其中'pin_code'(是一个数组)与我拥有的pin码列表匹配。密码列表来自我通过以下代码设法获得的集合“地址”。但我无法从“产品”集合中获取与 PIN 码列表匹配的文档。

以下是我必须从集合“地址”中获取密码列表的代码

        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 ->

            }

    }

我尝试使用以下代码从集合“产品”中获取数据。但是使用此代码,只有当我的“pin_code”不是数组时,我才能获得产品列表。但由于某种原因,我不得不将 pin_code 设为数组,并且无法获取产品列表。

    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 {

        }
}

有人可以帮我解决这个问题吗?

谢谢。

【问题讨论】:

    标签: android firebase kotlin google-cloud-firestore


    【解决方案1】:

    我想从集合“products”中获取所有文档,其中“pin_code”(是一个数组)与我拥有的 pin 码列表匹配。

    您绝对可以使用 Query 的 whereArrayContainsAny(String field, List<? extends Object> values) 方法来做到这一点,该方法:

    创建并返回一个带有附加过滤器的新查询,该过滤器文档必须包含指定的字段,值必须是一个数组,并且该数组必须包含提供的列表中的至少一个值。

    假设您要从“products”集合中获取所有文档,其中“pin_code”数组包含具有两个值(“123456”和“159874”)的List,请使用以下代码行:

    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)
        }
    }
    

    【讨论】:

    • 太棒了。几行代码做得很好。我想知道我的方法总体上是否正确以及第一个代码块(getPins() 从“地址”集合中获取 Pin 码。
    • 对我来说看起来不错,但不要忘记数据是从 Firebase 异步加载的,这意味着任何需要来自数据库的数据的代码都需要在 onComplete/onSuccess 方法中,或者从那里。因此,您拥有的最佳选择是使用嵌套侦听器。
    • 我刚刚理解了应该从 onComplete/onSuccess 调用它的点。因为我不知道CallbacksCoroutineawaitsync 我正在从onComplete/onSuccess 调用其他方法。无论如何,我已经开始了我作为开发人员的旅程。感谢您一直以来的所有投入/帮助,并期待未来也是如此。
    【解决方案2】:

    这是使用 Array Contains 条件完成的,使用各种方法之一,您可以查看数组是否包含 some、any、all 和 not-in。

    val citiesRef = db.collection("products")
    
    citiesRef.whereIn("pin_code", listOf("123456", "150875"))
    

    获取此快照后,它将返回一组匹配的文档,然后您可以根据需要将其与应用逻辑的其他部分和辅助 Firestore 查询一起使用。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多