Не удается обновить значение узла в узле childAutoId для обновления значений словаря - PullRequest
2 голосов
/ 22 мая 2019

Я работаю над приложением отслеживания веса, когда я добавляю новые данные в firebase, оно работает правильно, но когда я обновляю данные с этой даты, новые данные добавляются с уникальным идентификатором существующих электронных писем, я хочу обновить вес текущих дат, еслия снова добавляю вес в эту дату [черный круг, показывающий, где я хочу обновить вес, а остальные данные - это то, где обновляются фактические данные

, вот и мой код.

@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 ]

1 голос
/ 22 мая 2019

В этом примере вы можете сделать 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, исходящий из пользовательского интерфейса 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)
        })
    }
}
0 голосов
/ 22 мая 2019

Чтобы найти решение, давайте сначала определим проблему.

Вот ваша структура

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

Единственная проблема со вторым методом состоит в том, чточто запрос не даст результатов, если дата не существует, поэтому вы должны убедиться, что она существует до обновления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...