我正在使用 Firebase 实时数据库函数 .orderByChild() 和 .equalTo() 来获取要更新的数据节点。但是,我似乎无法从查询中得到任何结果。
我的数据库结构
{
"4QEg0TWDbESiMX8Cu8cvUCm17so2" : {
"-LmGtXsgJbAvVS8gv5-E" : {
"createdAt" : 1565815876803,
"message" : "Hello",
"isSender" : false,
"sender" : {
"alias" : "",
"name" : "Person A",
"sid" : "mUO3DtYY2yRw3zkv4EmTlfldB3S2"
},
"sysStatus" : 0
},
"-LmGtt4nyuygG9B4s6__" : {
"createdAt" : 1565815967746,
"message" : "Hej!",
"isSender" : true,
"sender" : {
"alias" : "",
"name" : "Person B",
"sid" : "4QEg0TWDbESiMX8Cu8cvUCm17so2"
},
"sysStatus" : 0
},
"-LmJxcvL_Y7JmojxPiiK" : {
"createdAt" : 1565867281849,
"isSender" : true,
"message" : "111",
"sender" : {
"alias" : "",
"name" : "Person B",
"sid" : "4QEg0TWDbESiMX8Cu8cvUCm17so2"
},
"sysStatus" : 0
}
},
"mUO3DtYY2yRw3zkv4EmTlfldB3S2" : {
"222" : {
"createdAt" : 1565867281849,
"isSender" : true,
"message" : "Test",
"sender" : {
"alias" : "",
"name" : "Person A",
"sid" : "mUO3DtYY2yRw3zkv4EmTlfldB3S2"
},
"sysStatus" : 0
},
"333" : { <-- This is one node I wish to fetch
"createdAt" : 1565815967746,
"isSender" : false,
"message" : "123",
"sender" : {
"alias" : "",
"name" : "Person B",
"sid" : "4QEg0TWDbESiMX8Cu8cvUCm17so2" <-- This is the value I am trying to match
},
"sysStatus" : 0
}
},
"rKNUGgdKqdP68T0ne6wmgJzcCE82" : {
"-Lm_GTmNHyxqCqQl4D4Z" : { <-- This is one node I wish to fetch
"createdAt" : 1566140917160,
"isSender" : false,
"message" : "Sesame",
"sender" : {
"alias" : "",
"name" : "Person B",
"sid" : "4QEg0TWDbESiMX8Cu8cvUCm17so2" <-- This is the value I am trying to match
},
"sysStatus" : 5
}
}
}
我的代码
dbRoot.child('messages')
.orderByChild('sid')
.equalTo(userId)
.once('value', (senderSnapshot) => {
console.log('senderSnapshot', senderSnapshot.val())
console.log('senderSnapshot amount', senderSnapshot.numChildren())
senderSnapshot.forEach((sender)=>{
//Do the work!
})
})
代码日志
senderSnapshot null
senderSnapshot amount 0
我手动检查了有几个节点的“sid”设置为我要查找的“userId”。
为什么我没有从查询中得到任何结果?
看来我必须搜索 dbRoot.child('messages/rKNUGgdKqdP68T0ne6wmgJzcCE82') 才能获取我的值。 :/(然后对每个用户重复搜索) 下载/收集所有联系人然后循环访问每个用户联系人会产生多少额外数据开销?
最佳答案
Firebase 数据库查询允许您在特定位置的直接子节点中搜索每个子节点下固定路径处的值。因此:如果您知道要搜索其消息的用户,您可以执行以下操作:
dbRoot
.child('messages')
.child('mUO3DtYY2yRw3zkv4EmTlfldB3S2') // the user ID
.orderByChild('sender/sid')
.equalTo(userId)
请注意我在您的代码中所做的两项更改:
- 我们现在从
messages/mUO3DtYY2yRw3zkv4EmTlfldB3S2
开始搜索,以便它仅搜索该用户的消息。 - 现在,我们对
messages/mUO3DtYY2yRw3zkv4EmTlfldB3S2
下每个子项的sender/sid
属性进行排序/过滤。
通过组合这些,我们本质上是在子节点的平面列表中搜索每个子节点下路径处的特定匹配值。
在当前的数据结构中,无法查找所有用户中特定 sender/sid
值的所有消息。为了实现这一点,您必须添加额外的数据结构,本质上是反转当前数据。
"sender_messages": {
"mUO3DtYY2yRw3zkv4EmTlfldB3S2": {
"4QEg0TWDbESiMX8Cu8cvUCm17so2/-LmGtXsgJbAvVS8gv5-E": true,
},
"4QEg0TWDbESiMX8Cu8cvUCm17so2": {
"4QEg0TWDbESiMX8Cu8cvUCm17so2/-LmGtXsgJbAvVS8gv5-E": true,
"4QEg0TWDbESiMX8Cu8cvUCm17so2/-LmGtt4nyuygG9B4s6__": true,
"4QEg0TWDbESiMX8Cu8cvUCm17so2/-LmJxcvL_Y7JmojxPiiK": true,
"mUO3DtYY2yRw3zkv4EmTlfldB3S2/333": true,
"rKNUGgdKqdP68T0ne6wmgJzcCE82/Lm_GTmNHyxqCqQl4D4Z": true
},
"mUO3DtYY2yRw3zkv4EmTlfldB3S2": {
"mUO3DtYY2yRw3zkv4EmTlfldB3S2/222": true,
}
}
现在您可以通过阅读以下内容找到特定sender/sid
的消息:
dbRoot
.child('sender_messages')
.child('4QEg0TWDbESiMX8Cu8cvUCm17so2') // the sender ID
然后循环结果,并根据需要从每个路径加载单独的消息。
这在 NoSQL 数据库中很常见:您经常需要修改数据结构以允许您想要添加到应用程序中的用例。
另请参阅:
关于javascript - Firebase 实时数据库 - orderByChild 不返回任何结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57829392/