Can Swift return value from an async Void-returning block?

You should employ asynchronous (ie, escaping) completion handler yourself:

class func checkIfUserExists(uid: String, completion: @escaping (Bool) -> Void) {
    userRef.childByAppendingPath(uid).observeSingleEventOfType(.Value) { snapShot in
        if snapShot.value is NSNull {
            completion(false)
        } else {
            completion(true)
        }
    }
}

You can then call this like so:

MyClass.checkIfUserExists(uid) { success in
    // use success here
}

// but not here

In your revised question, you demonstrate the use of dispatch groups to make this asynchronous method behave synchronously. (Semaphores are also often used to the same ends.)

Two issues:

  1. This will deadlock if they dispatch their completion handler back to the main queue (and in many cases, libraries will do this to simplify life for us), because you're coincidentally blocking the very same thread they're trying to use. I don't know if that's what they've done here, but is likely.

    If you want to confirm this, temporarily remove dispatch group and then examine NSThread.isMainThread and see if it's running in main thread or not.

  2. You never should block the main thread, anyway. They provided an asynchronous interface for good reason, so you should use asynchronous patterns when calling it. Don't fight the asynchronous patterns, but rather embrace them.