无法更新childAutoId节点中的节点值以更新字典值

时间:2019-05-22 12:23:25

标签: swift firebase firebase-realtime-database

当我向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)

             }
         }
     }
 }

screenshot

2 个答案:

答案 0 :(得分:1)

在此示例中,您可以执行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)
        })
    }
}

答案 1 :(得分:0)

要找到解决方案,我们首先确定问题所在。

这是您的结构

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)

使用现有结构的另一种选择是查询日期等于所需日期的节点,然后获取该节点的密钥,然后更新子权重节点

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)
    })
}

第二种方法的唯一问题是,如果日期不存在,查询将不返回任何结果,因此您需要确保在进行更新之前这样做。