Firebase Queries aren't firing in the order I want, how can I fix this?

In my iOS app I'm trying to pull strings (from Google Firebase) to populate array friends, then iterate over that array to populate friendsMarkers with Markers. My problem is that the for loop in fetchFriendsMarkers never executes because friends[] returns an empty array. Is this an issue of synchronization? If so, how do I ensure friends is not empty before fetchFriendsMarkers() executes?

    var ref: DatabaseReference?
    var friends: [String] = []
    var friendsMarkers: [Marker] = []

    private func viewDidLoad(){
            ref = Database.database().reference()
            fetchFriends()
            fetchFriendsMarkers()
    }   

    private func fetchFriends(){
            let query = ref?.child("users").child((currentUser?.uid)!).child("Friends")
            query?.observe(.childAdded, with: { (snapshot) in
                let friend = snapshot.value as? NSDictionary
                let id = friend!["id"] as! String
                self.friends.append(id)
            })
            query?.observe(.childRemoved, with: { (snapshot) in
                let friend = snapshot.value as? NSDictionary
                let id = friend!["id"] as! String
                var index: Int
                for i in self.friends{
                    if i == id{
                        index = self.friends.index(of: i)!
                        self.friends.remove(at: index)
                    }
                }
            })
        }

        private func fetchFriendsMarkers(){
            for friend in self.friends {
                let query1 = ref?.child("user-locations").child(friend)
                query1?.observe(.childAdded, with: { (snapshot) in

                })
                query1?.observe(.childChanged, with: { (snapshot) in

                })
                query1?.observe(.childRemoved, with: { (snapshot) in

                })
            }
        }

Upvotes: 1

Views: 34

Answers (1)

Christian Abella
Christian Abella

Reputation: 5797

These are all asynchronous calls and that is why your other function was not called. You need to call the fetchFriendsMarkers inside your fetchFriends function when you receive the data and would suggest the following modifications:

private func fetchFriends(){
 let query = ref?.child("users").child((currentUser?.uid)!).child("Friends")
 query?.observe(.childAdded, with: { (snapshot) in
   let friend = snapshot.value as? NSDictionary
   let id = friend!["id"] as! String
   self.friends.append(id)
   // call fetchFriendMarkers when you receive the friend data
   self.fetchFriendsMarkers(id)
 })
 query?.observe(.childRemoved, with: { (snapshot) in
   let friend = snapshot.value as? NSDictionary
   let id = friend!["id"] as! String
   var index: Int
   for i in self.friends{
      if i == id{
         index = self.friends.index(of: i)!
         self.friends.remove(at: index)
      }
   }
 })
}

private func fetchFriendsMarkers(friend: String){
  let query1 = ref?.child("user-locations").child(friend)
     query1?.observe(.childAdded, with: { (snapshot) in

  })
  query1?.observe(.childChanged, with: { (snapshot) in

  })
  query1?.observe(.childRemoved, with: { (snapshot) in  
  })

}

...
fetchFriends()

Upvotes: 1

Related Questions