Unexpected non-void return value in void function error in function

code:

func returnusername(){

    guard let uid = Auth.auth().currentUser?.uid else { return  }

    guard (Auth.auth().currentUser?.uid) != nil else {return}

     Database.database().reference().child(uid).child("users").child("username").observeSingleEvent(of: .value){ (snapshot) in

      guard let username = snapshot.value as? String else {return}

      return username

}

}

When I try return username it outputs the following error: Unexpected non-void return value in void function. What am I doing wrong?

Answered by OOPer in 690656022

What am I doing wrong?

When you want to return a value from a closure, the closure must be declared as to return a value. But, the closure type in observeSingleEvent(of:with:) is not declared to return a value.

When you want to pass something after some asynchronous operation is finished, one traditional way is using the completion handler pattern.

In your case, something like this:

    func returnusername(completion: @escaping (String?)->Void) {
        guard let uid = Auth.auth().currentUser?.uid else {
            completion(nil)
            return
        }
        //guard (Auth.auth().currentUser?.uid) != nil else {return} //<- Duplicate check, is not needed
        Database.database().reference().child(uid).child("users").child("username").observeSingleEvent(of: .value){ (snapshot) in
            guard let username = snapshot.value as? String else {
                completion(nil)
                return
            }
            completion(username)
        }
    }

You can use it as follows:

    func someMethod() {
        returnusername { username in
            guard let username = username else {
                return
            }
            //Use `username` here...
            //...
        }
    }

You say:

func returnusername()

That is, your function returnusername returns no value (called "void")

But in returnusername, you say:

return username

So there is a contradiction, hence the error message.

You probably mean:

func returnusername() -> String
Accepted Answer

What am I doing wrong?

When you want to return a value from a closure, the closure must be declared as to return a value. But, the closure type in observeSingleEvent(of:with:) is not declared to return a value.

When you want to pass something after some asynchronous operation is finished, one traditional way is using the completion handler pattern.

In your case, something like this:

    func returnusername(completion: @escaping (String?)->Void) {
        guard let uid = Auth.auth().currentUser?.uid else {
            completion(nil)
            return
        }
        //guard (Auth.auth().currentUser?.uid) != nil else {return} //<- Duplicate check, is not needed
        Database.database().reference().child(uid).child("users").child("username").observeSingleEvent(of: .value){ (snapshot) in
            guard let username = snapshot.value as? String else {
                completion(nil)
                return
            }
            completion(username)
        }
    }

You can use it as follows:

    func someMethod() {
        returnusername { username in
            guard let username = username else {
                return
            }
            //Use `username` here...
            //...
        }
    }
Unexpected non-void return value in void function error in function
 
 
Q