Trying to get data from firebase Swift

Viewed 689

Ok, I have a function that has to find the average of the ratings, so I store the total amount of ratings and a total sum of ratings in my firebase (which works fine). I am trying to retrieve the data, but it seems that it doesn't even enter the codeblock of the .observeSingleEvent I am using the same approach when trying to update the values, which means I get them and I add the new rating to them and then I use the code below to update the values:

let ratingObject = [
   "uid" : (user?.uid)! as String,
   "totalRatings" : newRating as Int,
   "amountOfRatings" : newAmountOfRating as int
   ] as [String : Any]

dbRef.setValue(ratingObject)

It doesn't give an error and I am just lost

I tried to do it based on this tutorial: https://www.youtube.com/watch?v=JV9Oqyle3iE

The answers given in this thread : how parsing Firebase FDatasnapshot json data in swift are just crashing the app

private func FindAverage(uid: String) -> Int {

    var totalRatings = 0
    var amountOfRatings = 1
    let dbRef = Database.database().reference().child("ratings").child(uid)

    dbRef.observeSingleEvent(of: .value, with: { snapshot in

        let dict = snapshot.value as? [String:Any]
        totalRatings = dict?["totalRatings"] as? Int ??  0
        amountOfRatings = dict?["amountOfRatings"] as? Int ??  1

    }){ (error) in
        print(error.localizedDescription)
    }

    return((Int)(totalRatings/amountOfRatings))
}

Database structure enter image description here

Any tips and help is very appreciated!

2 Answers

You are trying to return value out of completion handler.

Your function should be like:

private func findAverage(byUid uid: String, completion: @escaping (_ average: Int) -> Void) {
    // ...
    dbRef.observeSingleEvent(of: .value, with: { snapshot in
        guard let dict = snapshot.value as? [String: Any] else {
            return
        }
        totalRatings = dict["totalRatings"] as? Int ?? 0
        amountOfRatings = dict["amountOfRatings"] as? Int ?? 1

        completion((Int)(totalRatings / amountOfRatings))
    })
}

Something like this, check Swift docs (about completion handlers etc.).

Try below code:

private func FindAverage(uid: String) -> Int {
  var totalRatings = 0
  var amountOfRatings = 1
  let dbRef = Database.database().reference().child("ratings").child(uid)
  dbRef.observeSingleEvent(of: .value, with: { snapshot in
     if snapshot.exists() {
        guard let dict = snapshot.value as? [String: Any] else {
           return
        }
        totalRatings = dict?["totalRatings"] as? Int ??  0
        amountOfRatings = dict?["amountOfRatings"] as? Int ??  1
     }
   }){ (error) in
      print(error.localizedDescription)
   }
   return((Int)(totalRatings/amountOfRatings))
}
Related