I can't get 3 values out of a function, I get an error message:
Cannot convert value of type '(String, String, String)' to closure result type 'Void'
this is the code:
func readDataUser() -> (uid: String, plan: String, role: String) {
let ref = Database.database().reference()
let userUid = AuthManager.shared.retrieveUid
let nodeUser = ref.child(RefDatabase.users.rawValue).child(userUid())
nodeUser.observeSingleEvent(of: .value) { snapshot in
let uid = snapshot.childSnapshot(forPath: "uid").value as? String ?? "no name"
let plan = snapshot.childSnapshot(forPath: "plan").value as? String ?? "no name"
let role = snapshot.childSnapshot(forPath: "role").value as? String ?? "no name"
return (uid, plan, role)
// Cannot convert value of type '(String, String, String)' to closure result type 'Void'
}
// if return (uid, plan, role) i put here it doesn't give the error, but it doesn't print the values, they are empty
}
I would like you to print the values for me:
let dataUser = RealtimeManager.shared.readDataUser()
print("User data is: \(dataUser.uid) - \(dataUser.plan) - \(dataUser.role)")
As @vadian said, this is an async
task. Thus, you cannot treat it as normal sync
. I could prefer the new API async
rather than completion
.
Firstly, you need to wrap observeSingleEvent
completion in withUnsafeContinuation
:
func readDataUser() async -> (uid: String, plan: String, role: String) {
...
return await withUnsafeContinuation { continuation in
nodeUser.observeSingleEvent(of: .value) { snapshot in
let uid = snapshot.childSnapshot(forPath: "uid").value as? String ?? "no name"
let plan = snapshot.childSnapshot(forPath: "plan").value as? String ?? "no name"
let role = snapshot.childSnapshot(forPath: "role").value as? String ?? "no name"
continuation.resume(returning: (uid, plan, role))
}
}
}
Then get the value within Task
:
Task {
let dataUser = await self.readDataUser()
print("User data is: \(dataUser.uid) - \(dataUser.plan) - \(dataUser.role)")
}