我试图查询数据并将数据更新为firebase。但是我无法获取数据。看来该程序没有遇到参考我应该做什么来解决这个问题?
func getId(path:String, value:String?, completion: @escaping (String?) -> Void) {
let ref = Database.database().reference(withPath: path).queryOrdered(byChild: "name").queryEqual(toValue: value)
ref.observeSingleEvent(of: .childAdded, with: { snapshot in
print("running in getId")
completion(snapshot.key)
}) { (error) in
print(error.localizedDescription)
}
}
@objc func onTapConfirmed(){
self.getId(path: "patients", value: self.kardex?.patient?.name) { snapshotKey in
BookingViewController.kardexDict["patient"] = snapshotKey as AnyObject?
print("1:get patient name")
}
self.getId(path: "nurses", value: BookingTreatmentListController.nurseName) { snapshotKey in
BookingViewController.kardexDict["nurse"] = snapshotKey as AnyObject?
print("2:get nurse name")
}
Database.database().reference().child("kardexes").child(BookingViewController.newKardex.id).updateChildValues(BookingViewController.kardexDict)
print("save kardexDict")
}
我希望得到以下结果
" 1:获取患者名称" ->"在getID中运行" ->" 2:获取护士名称" ->"在getid中运行" ->"保存kardexdict"
但我得到了
" 1:获取患者名称" ->" 2:获取护士名称" ->"保存kardexdict"
和kardexdict中的数据是不正确的,因为数据未从function getID((获得我该怎么做才能遵循我期望的订单。
您以错误的方式使用firebase:
-
observeSingleEvent
异步运行,因此事件的顺序将是:"在getid中运行" ->" 1:获取患者名称" -
updateChildValues
通常会在任何observeSingleEvent
完成之前调用
因此,您首先在拿到病人或护士名称之前将空的(?(kardexDict
写信给Firebase。
另外,请注意completion
闭合在主线程中不运行。因此,您可能会观察到一些不可预测的并发问题/种族条件。您要做的就是等待所有observeSingleEvent
完成,然后再写数据。
更新
因此,您的想法的或多或少或多或少地转移可以看起来像这样(可能不完全编译,因为我没有您的环境运行(:
func getId(path:String, value:String?, completion: @escaping (String?) -> Void) {
let ref = Database.database().reference(withPath: path).queryOrdered(byChild: "name").queryEqual(toValue: value)
ref.observeSingleEvent(of: .childAdded, with: { snapshot in
print("running in getId")
completion(snapshot.key)
}) { (error) in
print(error.localizedDescription)
}
}
@objc func onTapConfirmed(){
let patientName = self.kardex?.patient?.name
let nurseName = BookingTreatmentListController.nurseName
self.getId(path: "patients", value: patientName) { snapshotKey in
print("1:got patient")
let patient = snapshotKey as AnyObject?
self.getId(path: "nurses", value: nurseName) { snapshotKey in
print("2:got nurse")
let nurse = snapshotKey as AnyObject?
DispatchQueue.Main.async {
print("save kardexDict (in main thread!")
BookingViewController.kardexDict["patient"] = patient
BookingViewController.kardexDict["nurses"] = nurse
let kardexes = Database.database().reference().child("kardexes")
kardexes.child(BookingViewController.newKardex.id).updateChildValues(BookingViewController.kardexDict)
}
}
}
}
尽管如此,可能不是,因为涉及两个独立的网络呼叫(首先是患者,然后是护士(。也许您最好使用observe
代替observeSingleEvent
。