0

I am making a completion handler for a function which will return a list of objects. When it return value for first time, it works well. But when any change happen into firebase database and again observe gets called, array size gets doubled up. Why it's getting doubled up?

func getStadiums(complition: @escaping ([Stadium]) -> Void){
  var stadiums: [Stadium] = []
  let stadiumRef = Database.database().reference().child("Stadium")
  stadiumRef.observe(.value, with: { (snapshot) in
    for snap in snapshot.children {
      guard let stadiumSnap = snap as? DataSnapshot else {
        print("Something wrong with Firebase DataSnapshot")
          complition(stadiums)
          return
      }
      let stadium = Stadium(snap: stadiumSnap)
      stadiums.append(stadium)
    }
    complition(stadiums)
  })
}

And calling like this

getStadiums(){ stadiums
  print(stadiums.count) // count gets doubled up after every observe call
}
sz ashik
  • 881
  • 7
  • 20

4 Answers4

4

The code you're using declares stadiums outside of the observer. This means any time a change is made to the value of the database reference, you're appending the data onto stadiums without clearing what was there before. Make sure to remove the data from stadiums before appending the snapshots again:

func getStadiums(complition: @escaping ([Stadium]) -> Void){
  var stadiums: [Stadium] = []
  let stadiumRef = Database.database().reference().child("Stadium")
  stadiumRef.observe(.value, with: { (snapshot) in
    stadiums.removeAll() // start with an empty array
    for snap in snapshot.children {
      guard let stadiumSnap = snap as? DataSnapshot else {
        print("Something wrong with Firebase DataSnapshot")
          complition(stadiums)
          return
      }
      let stadium = Stadium(snap: stadiumSnap)
      stadiums.append(stadium)
    }
    complition(stadiums)
  })
}
Jen Person
  • 7,356
  • 22
  • 30
0

This line stadiumRef.observe(.value, with: { (snapshot) in ... actually adding an observer that will be called everytime your stadium data is changed.

Because you called it twice by using getStadiums(){ stadiums ..., the total observer added will be 2.

That makes the line stadiums.append(stadium) called twice in the second call.

My suggestion would be to use stadiumRef.observe() once without calling it from getStadiums().

ramacode
  • 914
  • 6
  • 14
0

Create a Model as below

class OrderListModel: NSObject {
    var Order:String?
    var Date:String?
}

Use the below code in the view controller and you should be able to see content in your tableview

func getOrdersData()  {
    self.orderListArr.removeAll()
    let ref = Database.database().reference().child(“users”).child(user).child("Orders")

        ref.observe(.childAdded, with: { (snapshot) in
            print(snapshot)
            guard let dictionary = snapshot.value as? [String : AnyObject] else {
                return
            }

            let orderObj = OrderModel()
            orderObj.Order = dictionary[“Order”] as? String
            orderObj.Date = dictionary[“Date”] as? String

            self.orderListArr.append(orderObj)
            self.tableView.delegate = self
            self.tableView.dataSource = self
            self.tableView.reloadData()

        }, withCancel: nil)
}
Yogesh Tandel
  • 1,738
  • 1
  • 19
  • 25
0
func ListenForChildrenAdded() {

let registerToListenTo = "YourPathHere"

ref.child(registerToListenTo).observeSingleEvent(of: .value) { (snapshot) in
    
    let initialChildren = snapshot.childrenCount
    var incrementer = 0
    
    ref.child(registerToListenTo).observe(.childAdded, with: { (snapshot) in
        
        incrementer += 1
        print("snapshot: \(snapshot.key) #\(incrementer)")

        if incrementer == initialChildren {
            print("-> All children found")
        } else if incrementer > initialChildren {
            print("-> Child Was Added - Run Some Code Here")
        }
        
    })
}}
Stotch
  • 373
  • 3
  • 10