I've the following boolean function:
func checkIfLocateAcessGiven(uid: String) -> Bool {
print("checkIfLocateAcessGiven")
var currentUserID = UserDefaults.standard.string(forKey: "currentUserID")
var statusStr = false
print("checkIfLocateAcessGiven statusStr 1: \(statusStr)")
Database.database().reference().child("Locate").child(currentUserID!)
.observeSingleEvent(of: .value, with: { (dataSnapshot) in
if(dataSnapshot.exists()){
if(dataSnapshot.hasChild("RequestedTo")){
if(dataSnapshot.childSnapshot(forPath: "RequestedTo").hasChild(uid)){
var status = dataSnapshot.childSnapshot(forPath: "RequestedTo").childSnapshot(forPath: uid).value as! String ?? ""
if(status == "true"){
statusStr = true
print("checkIfLocateAcessGiven statusStr 2: \(statusStr)")
}else {
statusStr = false
print("checkIfLocateAcessGiven statusStr 3: \(statusStr)")
}
}else {
statusStr = false
print("checkIfLocateAcessGiven statusStr 4: \(statusStr)")
}
}else {
statusStr = false
print("checkIfLocateAcessGiven statusStr 5: \(statusStr)")
}
}else {
statusStr = false
print("checkIfLocateAcessGiven statusStr 6: \(statusStr)")
}
})
print("checkIfLocateAcessGiven statusStr 7: \(statusStr)")
return statusStr
}
When I call this function I get the following results:
checkIfLocateAcessGiven
checkIfLocateAcessGiven statusStr 1: false
checkIfLocateAcessGiven statusStr 7: false
checkIfLocateAcessGiven statusStr 2: true
Since false is returned at first, my code takes a different flow, and later true is returned, how can I wait in the boolean function until the real value is checked. There's delay of approx. 1 second between
checkIfLocateAcessGiven statusStr 7: false
and
checkIfLocateAcessGiven statusStr 2: true
I want the boolean to wait and check the real value and then return the value, in this case true but it's currently returning false
Could someone please help me with this?
This is an asynchronous function, meaning that it cannot return synchronously a result which it needs to obtain asynchronously, for example from a web service, like Firebase.
You can't (or rather shouldn't) wait for it, and instead use a callback to notify when the value has been obtained.
If you don't know about async programming, there are a lot of material online and you should definitely read more about it, because this answer won't be comprehensive.
The basic idea is that your async function takes in a closure that would be invoked on completion:
func checkIfLocateAcessGiven(uid: String, completion: (Bool) -> Void) {
// your setup code
Database.database().reference().child("Locate").child(currentUserID!)
.observeSingleEvent(of: .value, with: { (dataSnapshot) in
// checks, ifs, etc..
// whenever you have the result
completion(true) // or completion(false)
}
}
The caller would specify the completion callback, which would be invoked asynchronously:
print("before")
checkIfLocateAcessGiven(uid: "1234") { result in
print("async call result: ", result)
// do whatever you need to do with the result
}
print("after")
The output of the above would be something like this:
before
after
async call result: true
The first two lines would print immediately one after another, and the third line would take a while, however long the Firebase call takes.