首页 > 解决方案 > 如何在firebase firestore中的数据中应用具有不同深度级别的多个where子句?

问题描述

我正在尝试从具有多个 where 条件的 Firebase Firestore 获取数据。问题是在不同层次上适用的条件。`

db.collection("users")
            .whereEqualTo("sex", oppositeSex)
            .whereNotEqualTo("connections/likedBy", true) // this is the additional condition I need
            .whereNotEqualTo("connections/dislikedBy", true) // this is the additional condition I need
            .get()
            .addOnCompleteListener { task ->`.....

这是数据库结构

数据库结构

在这些查询中,我试图实现的是一种能够将路径(数据库引用)扩展到子集合的方法。我使用“/”只是为了说明需要做什么。如何做到这一点?

更新:

    private fun retrieveOppositeSexUsers() {

    try {
        var oppositeSex = if (currentUserSex == "Male") "Female" else "Male"

        db.collection("users")
            .whereEqualTo("sex", oppositeSex)
            .get()
            .addOnCompleteListener { task ->
                if (task.isSuccessful) {
                    arrlstOppositeSexUsers.clear()
                    try {
                        task.result.apply {
                            db.collection("users").document().collection("connections")
                                .whereNotEqualTo(strCurrentUserID, true).get()
                                .addOnCompleteListener { task ->
                                    for (document in task.result!!) {
                                        val userID = document.id
                                        val name = document.data["username"].toString()
                                        val profileImageURL =
                                            document.data["profileImageURL"].toString()
                                        val user = User(userID, name, profileImageURL)

                                        arrlstOppositeSexUsers.add(user)
                                        flingContainer.adapter = userAdpater
                                        userAdpater!!.notifyDataSetChanged()
                                        Log.d(TAG, document.id + " => " + document.data)
                                    }
                                }
                        }
                    } catch (e: Exception) {
                        e.printStackTrace()
                    }

                } else {
                    Log.d(TAG, "Error getting documents.", task.exception)
                }
            }

    } catch (e: Exception) {
        e.printStackTrace()
    }

}

指数

标签: androidfirebasekotlingoogle-cloud-firestore

解决方案


如何在 Firebase Firestore 中的数据中应用具有不同深度级别的多个 where 子句?

你不能这样做。Firestore 中的查询很浅,它只能从运行查询的集合中获取文档。您无法在单个查询中从顶级集合和子集合中获取文档。Firestore 不支持一次性跨不同集合进行查询。单个查询只能使用单个集合中文档的属性。

在您的特定用例中,我能想到两种解决方案。第一个是在“connections”集合下的每个文档中添加您感兴趣的字段,例如“sex”并使用如下所示的查询:

FirebaseAuth.getInstance().currentUser?.apply {
    db.collection("users").document(uid).collection("connections")
        .whereEqualTo("sex", oppositeSex)
        .whereEqualTo(uid, true)
}

如果您无法更改数据库架构,那么您拥有的第二个选项是执行两个单独的查询。第一个是:

db.collection("users")
        .whereEqualTo("sex", oppositeSex)
        .get()
        .addOnCompleteListener {/* ... /*}

获得结果后,执行第二个查询,如下所示:

FirebaseAuth.getInstance().currentUser?.apply {
    db.collection("users").document(uid).collection("connections")
        .whereEqualTo(uid, true)
}

如果您只需要两个查询,那么您可以使用Tasks#whenAllSuccess()方法,如我在以下帖子中的回答中所述:

请注意,在这两个查询中,我都使用了对 的调用.whereEqualTo(uid, true),这是因为在您的“likedBy”文档中,您只有一个属性,它实际上是 UID。此属性的值为 true。当您对 Firestore 集合执行查询时,无需指定任何文档。但是,如果您查询子集合,则应在引用中指定位于第一个集合和子集合之间的文档。

致电:

FirebaseAuth.getInstance().currentUser?.apply {
    db.collection("users").document(uid).collection("connections")
        .whereNotEqualTo("connections/likedBy", true)
}

只有当您的架构以这种方式构建时,才会起作用:

Firestore-root
  |
  --- users (collection)
       |
       --- $uid (document)
            |
            --- connections (collection)
                  |
                  --- likedBy (document)
                       |
                       --- connections (object/map)
                             |
                             --- likedBy: true

但实际上并非如此。


推荐阅读