在Firebase数据库中搜索子节点
在Firebase数据库中搜索子节点
Firebase结构
嗨,我正在尝试弄清楚如何在我的Firebase数据库中查询jobBrand和jobName,并将其存储在tableView中。我将在每个Job Brand下存储更多信息,如果可能的话,我希望保持这种结构。到目前为止,如果它们处在同一级别上,我可以使tableView读取这两个字段,所以结构将是:
tbaShootApp -> Jobs -> Job Brand > data.
我无法弄清楚如何查询下一级并将其存储在tableView中。这可行吗?
我正在使用字典存储工作信息:
class Job: NSObject {
var id: String?
var jobBrand: String?
var jobName : String?
var director : String?
var jobInfo : jobInfo?
init(dictionary: [String: AnyObject]) {
self.id = dictionary["id"] as? String
self.jobBrand = dictionary["jobBrand"] as? String
self.jobName = dictionary["jobName"] as? String
self.director = dictionary["Director"] as? String
}
}
以下是查询数据的代码 - 我在superViewDidLoad中有函数'fetchJobs'。
func fetchJobs() {
Database.database().reference().child("Jobs").observe(.childAdded) { (snapshot) in
if let dictionary = snapshot.value as? [String: AnyObject] {
let job = Job(dictionary: dictionary)
job.id = snapshot.key
self.jobs.append(job)
//this will crash because of background thread, use dispatch_async to fix
DispatchQueue.main.async(execute: {
self.tableView.reloadData()
})
}
}
}
JSON
{
"Jobs" : {
"Candycrush" : {
"cameraInfo" : {
"cameraBody" : "A",
"cameraBrand" : "Arri",
"cameraType" : "Alexa"
},
"jobInfo" : {
"jobBrand" : "CandyCrush",
"jobName" : "Winter"
}
},
"Honda" : {
"cameraInfo" : {
"cameraBody" : "A",
"cameraBrand" : "Arri",
"cameraType" : "Alexa XT"
},
"jobBrand" : "Honda",
"jobName" : "Comet"
},
"WWF" : {
"cameraInfo" : {
"cameraBody" : "A",
"cameraBrand" : "Red",
"cameraType" : "Epic"
},
"jobInfo" : {
"jobBrand" : "WWF",
"jobName" : "Eye"
}
}
}
}
问题的出现原因:根据更新部分,问题似乎是由于查询深度较深,但只需要获取jobBrand和jobName这两个属性,而当前的查询方法无法满足需求。
解决方法:根据更新部分提供的解决方法,可以使用Firebase数据库的查询方法来实现。首先,根据jobBrand属性进行查询,然后使用observeSingleEvent方法来获取一次数据。查询代码如下:
Database.database().reference().child("Jobs").queryOrdered(byChild: "jobInfo/jobBrand").queryEqual(toValue: "JobBrandYouWant").observeSingleEvent(of: .value, with: { snapshot in
if let dictionary = snapshot.value as? [String: AnyObject] {
let job = Job(dictionary: dictionary)
job.id = snapshot.key
self.jobs.append(job)
}
})
原始答案:根据原始答案提供的代码,当前的查询方法会返回所有jobs节点下的数据,包括Job Brand -> jobinfo等子节点。如果只想获取较少的数据,则需要知道jobBrand、jobinfo或两者都知道。以下是一个修复代码示例:
Database.database().reference().child("Jobs").observe(.childAdded, with: { snapshot in
for child in snapshot.children { // 遍历snapshot,并将每个“job”转换为自己的字典
let child = child as? DataSnapshot
if let key = child?.key {
if let dictionary = child?.value as? [String: AnyObject] {
let job = Job(dictionary: dictionary)
job.id = key
self.jobs.append(job)
}
}
}
})
另外,参考文档提供了一个关于如何遍历snapshot的示例代码:
_commentsRef.observe(.value) { snapshot in
for child in snapshot.children {
...
}
}
对于后续的问题,可以根据jobBrand节点来查询jobInfo节点。可以参考这个问题的解决方法:stackoverflow.com/questions/40713137/…
问题的出现原因:在Firebase数据库中搜索子子项(sub child)。
解决方法:使用.child("Jobs").observe(.childAdded)函数来观察每次添加新的Jobs。同时,可能还需要观察列表中的删除操作。如果正在创建一个表格或者其他类似的列表,那么几乎每一行都需要单独观察该工作项。例如,第一行会观察Jobs/Candycrush的变化,第二行会观察Jobs/Honda的变化,以此类推。每一行(或者屏幕、面板、气泡、选项卡等)都会单独观察相应的内容。
另外,很可能在顶层的标题(如Honda、Candycrush等)是一个ID字符串。可以使用UUID或者让Firebase自动生成。然后,可以使用一个名为"Title"的字段来表示Honda等的标题。在这里将实际标题作为ID是非常不寻常的(因为这样就无法更改/编辑标题了)。