首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >无法更新childAutoId节点中的节点值以更新字典值

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

Stack Overflow用户
提问于 2019-05-22 20:23:25
回答 2查看 68关注 0票数 2

我正在使用体重跟踪应用程序,当我将新数据添加到firebase时,它工作正常,但当我从该日期更新数据时,新数据添加了现有的电子邮件唯一id,如果我在该日期再次添加权重,我想要更新当前日期的权重[黑色圆圈显示我想要更新权重的位置,其余的其他数据是实际数据更新的位置

下面是我的代码。

代码语言:javascript
复制
@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)

             }
         }
     }
 }

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-05-22 21:18:19

在这个示例中,您可以执行一个query来查找日期与您有兴趣在找到时更新的日期相匹配的node。该查询将返回节点的key (对于childByAutoId节点),您可以使用该节点更新子weight

代码语言:javascript
复制
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,并且正在考虑。

通过将一些操作拆分成变量实例并像这样重用它们,还可以使该函数更具可读性:

代码语言:javascript
复制
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)
        })
    }
}
票数 2
EN

Stack Overflow用户

发布于 2019-05-23 02:34:56

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

这是你的结构

代码语言:javascript
复制
Weighttracker
    user_uid_0
       child_by_auto_id_0
          date: "19.05.2019"
          weight: "236"

假设您想要更新该日期的权重,下面是更新代码

代码语言:javascript
复制
self.ref.child("WeightTracker").child(userid).updateChildValues(dict)

请记住,当使用updateChildValues时,如果它们不存在,它们将被添加。下面是代码更新这些子值的路径

代码语言:javascript
复制
WeightTracker/uid/values being updated here

当你想要的是

代码语言:javascript
复制
WeighTtracker/uid/childByAutoId/values being updated here
                  ^^^^^^^^^^^^^

问题是你不知道childByAutoId是什么,所以你不能直接更新数据。

有两种解决方案;一种是使用日期作为节点的键,这意味着需要更改结构

代码语言:javascript
复制
WeightTracker
    user_uid_0
       20190519
          weight: "236"

然后更新就变得很简单了

代码语言:javascript
复制
let userid = Auth.auth().currentUser.uid
let pathRef = self.ref.child(WeightTracker).child(userid).child(date)
pathRef.child("weight").setValue(weight)

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

代码语言:javascript
复制
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)
    })
}

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56256736

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档