ios - 如何在 Firebase IOS 中搜索值
问题描述
我的queryOrdered()
功能有问题,我真的不知道如何处理......
假设我的数据库结构是:
Planes{
Uid{
SE{
AutoID{
.Auto-Id
.Picture
.Registration
.Type
.model
}
AutoID{
//Same as first one
}
}
ME{
AutoID{
//Same as first one
}
}
}}
在我的数据库的这一部分,我想运行搜索.Registration
所以我被设置为我的参考Planes > UId
在执行此代码之后:
var acftPickerSelected = aircrafts[listAcftsPicker.selectedRow(inComponent: 0)]
if let user = Auth.auth().currentUser{
// user is connect
let ref = Database.database().reference()
let userID = Auth.auth().currentUser?.uid
let ev = ref.child("Planes").child(userID!)
ev.queryOrdered(byChild: "Registration").queryEqual(toValue: acftPickerSelected).observeSingleEvent(of: .value) { (snapshot: DataSnapshot) in
for child in snapshot.children {
let value = snapshot.value as? NSDictionary
self.pickerRegi = value?["Registration"] as? String ?? "..unknown.."
self.stdbPickerType = value?["Type"] as? String ?? "..unknown.."
self.pickerModel = value?["model"] as? String ?? "..unknown.."
print("Avion : \(self.pickerRegi) - \(self.pickerModel) - \(self.stdbPickerType)")
}
}
但出现此消息:
2018-11-27 18:03:54.797824+0100 XXXXXXXXXX[12954:527986] 5.10.0 - [Firebase/Database][I-RDB034028] 使用未指定的索引。您的数据将在客户端下载和过滤。考虑将 /Planes/BJMhmQzJXldULc5X9Y2WzjFEs9a2 中的 ".indexOn": "Registration" 添加到您的安全规则中以获得更好的性能
所以我一直在像这样在firebase上添加规则:
{"rules": {
"Planes":{
"$uid":{
".indexOn": ["Registration"],
".write": "$uid === auth.uid",
".read": "$uid === auth.uid"
}
},
".read": true,
".write": true}}
现在错误消息不再出现,但在这部分没有发生任何事情:
self.pickerRegi = value?["Registration"] as? String ?? "..unknown.."
self.stdbPickerType = value?["Type"] as? String ?? "..unknown.."
self.pickerModel = value?["model"] as? String ?? "..unknown.."
print("Avion : \(self.pickerRegi) - \(self.pickerModel) - \(self.stdbPickerType)")
我该如何解决?
谢谢你的帮助。
解决方案
这里发生了两件事;
- 索引开启
- 观察者
在这种情况下, indexOn 不是问题。
indexOn 在生产应用程序中最重要,它基本上是查询的性能提升。对于测试,首先消除该变量,因为它不是问题的原因。暂时将规则重置为默认值
{
"rules": {
".read": "auth != null",
".write": "auth != null"
}
}
真正的问题是观察,因为它不够深,无法到达您尝试获取的数据。你错过了“SE”级别。这里重新写
let uidRef = ref.child("Planes").child(userID)
let seRef = uidRef.child("SE") //this is the child node to query
seRef.queryOrdered(byChild: "Registration").queryEqual(toValue: acftPickerSelected)
.observeSingleEvent(of: .value) { snapshot in
for child in snapshot.children {
let childSnap = child as! DataSnapshot
let dict = childSnap.value as! [String: Any]
let reg = dict["Registration"] as? String ?? "No Reg"
let mod = dict["model"] as? String ?? "No Model"
print(reg, mod)
}
}
它在您的问题中的编写方式,查询将查询下一个级别:它期望直接在 SE 和 ME 节点下找到一个 Registration 节点。但是这些节点只包含 autoId 节点。
编辑:
通过展平(非规范化)来改变结构,这也是另一种选择
Planes
Uid
AutoID
.Auto-Id //note, if the is the same as the key, its not needed
.Picture
.Registration
.Type
.model
.se_or_me: "SE"
AutoID
.Auto-Id
.Picture
.Registration
.Type
.model
.se_or_me: "ME"
推荐阅读
- python - 最小化与 n 维点集的欧几里得距离
- php - 使用匿名函数进行 PHP 单元测试
- python - 为什么 pip install 对我来说不断失败?
- asynchronous - 如何在 go lang 中进行非阻塞 http 请求?
- c++ - 派生类中纯虚基方法的特化
- python - 当我的蛇碰到它时,苹果不会消失
- django - 将 django-admin startproject newDjango 作为无效语法执行时出现错误
- websocket - 有没有办法用颤振实现socket.io?
- java - 自动执行需要 python 解释器的 JAR
- http - 为什么 dio 发布空表单数据?