Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wait for completion handler to finish before returning

    func checkUsername(username: String) -> Bool {
        var avalible = true
        
        Database.database().reference().child("usernames").child(username).observeSingleEvent(of: .value, with: { snapshot in
            if snapshot.exists() {
                print("exists")
                avalible = false
            }
        })
        
        return available
    }

I'm trying to check if a username exists.
I've already tried multiple things, but it seems like the function always returns before the completion handler even finishes and always gives the same output (true) even if the username is already taken.

Does somebody have an idea how to „wait“ for the completion handler first to finish before returning the „available“ variable?

An explanation with the answer would be excellent.
Thanks.

like image 201
David Avatar asked Jun 24 '26 23:06

David


1 Answers

You cannot return something from an asynchronous task. Your code – with fixed typos – returns true even before the database request has been started.

Maybe there is a native async/await version of observeSingleEvent but in any case you can use a Continuation

func checkUsername(username: String) async -> Bool {
    return await withCheckedContinuation { continuation in
        Database.database().reference().child("usernames").child(username).observeSingleEvent(of: .value, with: { snapshot in
            continuation.resume(returning: !snapshot.exists())
        })
    }
}

And call it

Task {
   let isAvailable = await checkUsername(username: "Foo")

}
like image 78
vadian Avatar answered Jun 26 '26 13:06

vadian