Slygoth
Slygoth

Reputation: 333

Having issue with getting data from google firebase trying to use completion handler

I'm trying to create a completion handler for some data in my firebase database. I'm trying to use a while loop but nothing is happening. Code is below:

func ifUserIsMember(counter: Int, completionHandler: @escaping ((_ exist : Bool) -> Void)) {
    let ref = FIRDatabase.database().reference()

    ref.child("Test").child("\(counter)").observeSingleEvent(of: .value, with: { (snapshot) in
        if snapshot.exists(){
            let value = snapshot.value as? NSDictionary
            test1 = value?["cal1"] as! String
            test2 = value?["cal2"] as! String
            test3 = value?["cal3"] as! String
            completionHandler(true)
        }else{
            print("user is not a member of a team")
            completionHandler(false)
        }
    })
}

//called this in viewDidLoad

    var counter = 0
    var ref: FIRDatabaseReference!
    ref = FIRDatabase.database().reference()
        while counter < 6 {
        ifUserIsMember(counter: counter + 1) { (exist) -> () in
            if exist == true {
                print("Found something")

                counter += 1
            }
            else {
                print("NO DATA")
            }
        }
      }

I'm trying to use a while loop to get all the data but it's not working. It won't come out of the loop and start over

Upvotes: 0

Views: 96

Answers (2)

Vlad Pulichev
Vlad Pulichev

Reputation: 3272

Your code with some adds. Should work

 func ifUserIsMember(counter: Int, completionHandler: @escaping (_ exist : Bool) -> Void)) {
     let ref = FIRDatabase.database().reference()

     ref.child("Test").child("\(counter)").observeSingleEvent(of: .value, with: { (snapshot) in
         if snapshot.exists(){
            let value = snapshot.value as? NSDictionary
            test1 = value?["cal1"] as! String
            test2 = value?["cal2"] as! String
            test3 = value?["cal3"] as! String
            completionHandler(true)
        } else {
            print("user is not a member of a team")
            completionHandler(false)
        }
    })
}

//called this in viewDidLoad

var counter = 0
var ref: FIRDatabaseReference!
ref = FIRDatabase.database().reference()

while counter < 6 {
    ifUserIsMember(counter: counter + 1,
                   completionHandler: { existing in
        if existing {
            print("Found something")
        } else {
            print("NO DATA")
        }
   })

   counter += 1 // or you will have infinite loop
}

If you want to load an array of objects, for tableView for example, you should make another one function with completion handler. Something like

// for example it will return [String]
func getAllObjects(completion: (_ hasFinished: [String]) -> Void) {
    var arrayToReturn = [String]()
    var countOfChecked = 0 
    while counter < 6 {
         ifUserIsMember(counter: counter + 1,
                        completionHandler: { existing in
             var countOfChecked += 1
             if existing {
                 print("Found something")
                 arrayToReturn(//append some data)
                 if countOfChecked == 6 { // its your number (6)
                     completion(arrayToReturn)
                 }
             } else {
                 print("NO DATA")
             }
         })

         counter += 1 // or you will have infinite loop
    }
}

Something like this. You should get the idea.

Hope it helps

Upvotes: 1

Dave Weston
Dave Weston

Reputation: 6635

I'm not very familiar with Firebase and I'm not sure what you're trying to accomplish exactly, but updating counter in the completion handler isn't going to work.

If you put a log statement at the top of your ifUserIsMemberFunc, like: print("counter: \(counter)"), you might be surprised by the output.

If I'm reading your code correctly, you've basically got an infinite loop that creates Firebase queries to check for the existence of the child at 1.

If you want to run those queries in parallel, you'll want to put the counter += 1 outside of the completion block. However, then you'll need to wait for all of the queries to complete. (DispatchGroup is a good option.)

If you want to do something else, there are other options. Hope this helps!

Upvotes: 1

Related Questions