android - 如何在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()
}
}
解决方案
如何在 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
但实际上并非如此。
推荐阅读
- docker - Docker撰写部署停机时间与capistrano?
- javascript - 从 InAppBrowser 读取 localStorage
- lua - (LUA) 需要帮助将命令发送到 Web 服务器
- python - 将 python 脚本翻译成 qt 或 c++
- selenium - 按子级文本选择节点
- python - Flask 中有很多字段时如何更新记录。Python
- java - 如何将 java.util.Date 转换为 XMLGregorianCalendar
- regex - 如何在开始时限制空格?
- android - 嵌套函数不在声明处执行
- gstreamer - 向 gst_video_convert_sample() 添加属性