我正在使用体重跟踪应用程序,当我将新数据添加到firebase时,它工作正常,但当我从该日期更新数据时,新数据添加了现有的电子邮件唯一id,如果我在该日期再次添加权重,我想要更新当前日期的权重[黑色圆圈显示我想要更新权重的位置,其余的其他数据是实际数据更新的位置
下面是我的代码。
@IBAction func addButton(_ sender: UIButton) {
let time = Date()
let formatter = DateFormatter()
formatter.dateFormat = "dd.MM.yyyy"
let formatteddate = formatter.string(from: time as Date)
if formatteddate == addDate.text!{
self.UpdateTaskWithName(name: addWeight.text!, date: addDate.text!) { (success) in
print("**** TASK UPDATED *******")
DispatchQueue.main.async {
self.navigationController?.popViewController(animated: true)
}
}
}else{
if let text = self.addWeight.text{
if let date = self.addDate.text{
self.saveTaskWithName(name: text, date: date, completionHandler: { (success) in
print("**** NEW TASK ADDED *******")
DispatchQueue.main.async {
self.navigationController?.popViewController(animated: true)
}
})
}
}
}
}
func saveTaskWithName(name:String,date:String, completionHandler:@escaping ((_ success:Bool)->Void)){
let dict = ["weight": name, "date" : date] as [String : Any]
if let userid = Auth.auth().currentUser?.uid{
self.ref.child("WeightTracker").child(userid).childByAutoId().setValue(dict) { (error, reference) in
if let err = error{
print(err.localizedDescription)
}else{
// data save successfully
completionHandler(true)
}
}
}
}
func UpdateTaskWithName(name:String,date:String, completionHandler:@escaping ((_ success:Bool)->Void)){
let dict = ["weight": name, "date" : date] as [String : Any]
if let userid = Auth.auth().currentUser?.uid{
self.ref.child("WeightTracker").child(userid).updateChildValues(dict) { (error, reference) in
if let err = error{
print(err.localizedDescription)
}else{
// data save successfully
completionHandler(true)
}
}
}
}
发布于 2019-05-22 21:18:19
在这个示例中,您可以执行一个query
来查找日期与您有兴趣在找到时更新的日期相匹配的node
。该查询将返回节点的key
(对于childByAutoId
节点),您可以使用该节点更新子weight
func UpdateTaskWithName(name:String, date:String, completionHandler:@escaping ((_ success:Bool)->Void)){
if let userid = Auth.auth().currentUser?.uid {
self.ref.child("WeightTracker")
.child(userid)
.queryOrdered(byChild: "date")
.queryEqual(toValue: date)
.observeSingleEvent(of: .value, with: { snapshot in
self.ref.child("WeightTracker").child(userid).child(snapshot.key).child("weight").setValue(name)
})
}
}
这就是你的函数应该是什么样子,考虑到对于name
,你是指你的date
来自于UI TextField,并且正在考虑。
通过将一些操作拆分成变量实例并像这样重用它们,还可以使该函数更具可读性:
func UpdateTaskWithName(name:String, date:String, completionHandler:@escaping ((_ success:Bool)->Void)){
if let userID = Auth.auth().currentUser?.uid {
let userIDRef = self.ref.child("WeightTracker").child(userID)
let query = userIDRef.queryOrdered(byChild: "date").queryEqual(toValue: date)
query.observeSingleEvent(of: .value, with: { snapshot in
let childByAutoIDNodeKey = snapshot.key
let refToUpdate = userIDRef.child(childByAutoIDNodeKey).child("weight")
refToUpdate.setValue(name)
completionHandler(true)
})
}
}
发布于 2019-05-23 02:34:56
要找到解决方案,让我们首先确定问题所在。
这是你的结构
Weighttracker
user_uid_0
child_by_auto_id_0
date: "19.05.2019"
weight: "236"
假设您想要更新该日期的权重,下面是更新代码
self.ref.child("WeightTracker").child(userid).updateChildValues(dict)
请记住,当使用updateChildValues时,如果它们不存在,它们将被添加。下面是代码更新这些子值的路径
WeightTracker/uid/values being updated here
当你想要的是
WeighTtracker/uid/childByAutoId/values being updated here
^^^^^^^^^^^^^
问题是你不知道childByAutoId是什么,所以你不能直接更新数据。
有两种解决方案;一种是使用日期作为节点的键,这意味着需要更改结构
WeightTracker
user_uid_0
20190519
weight: "236"
然后更新就变得很简单了
let userid = Auth.auth().currentUser.uid
let pathRef = self.ref.child(WeightTracker).child(userid).child(date)
pathRef.child("weight").setValue(weight)
使用现有结构的另一种选择是查询date等于所需日期的节点,然后获取该节点的键,然后对子权重节点进行更新
func updateViaQuery() {
let uid = //users uid
let uidRef = self.ref.child("WeightTracker").child(uid)
let query = uidRef.queryOrdered(byChild: "date").queryEqual(toValue: "19.05.2019")
query.observeSingleEvent(of: .value, with: { snapshot in
let key = snapshot.key
let refToUpdate = uidRef.child(key).child("weight")
refToUpdate.setValue(weight)
})
}
第二种方法的唯一问题是,如果日期不存在,查询将不会返回任何结果,因此在执行更新之前,您需要确保日期存在。
https://stackoverflow.com/questions/56256736
复制相似问题