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

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (8)

我正在研究体重跟踪应用程序,当我向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)

             }
         }
     }
 }

提问于
用户回答回答于

在这个例子中,你可以query找到node你的日期与你想要更新的日期相匹配的地方。该查询将返回keychildByAutoId可用于更新子节点的节点(对于节点)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)
        })
    }
}
用户回答回答于

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

这是你的结构

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

The only issue with the second method is that the query would return no results if the date doesn't exist so you would want to ensure it does before doing an update.

所属标签

可能回答问题的人

  • 天使的炫翼

    16 粉丝531 提问35 回答
  • 富有想象力的人

    2 粉丝0 提问26 回答
  • 旺仔小小鹿

    社区 · 运营 (已认证)

    48 粉丝0 提问26 回答
  • 发条丶魔灵1

    6 粉丝525 提问25 回答

扫码关注云+社区

领取腾讯云代金券