Reputation: 451
I have been working with Firebase on Android for the last 12 months+, with success. I just switched over to Swift and am attempting to read data from the same Firebase database I created and have been using the last 12 months+. Since there is security applied to the FB DB the first thing I did was to get FB authentication (from Swift) working. This works. Now, I am trying to get a simple observeSingleEvent operational and am struggling.
The Firebase DB is the same old stuff. It has a users node off of the root. For starters I would just like to read in a user from the user's node. I know authentication is working because when I submit my email and password I receive a confirmation. When the email / password are wrong I do not get confirmation. Given this validates my connection to the DB and as a test I stuck the following code in right after login validation.
When I debug this it simply skips from the "self.ref?.child("users").observeSingleEvent..." to the bracket below. i.e. It never acknowledges there is data available, but there is data available.
To avoid anyone asking "What do you need?" What I am looking for is an answer to why I receive no data result set with the code below given there is data in the FB DB and I have been reading/writing that data on Android for the last 12+ months.
Any/all help is welcome as I cut my teeth on Swift / FB 4.0
@IBAction func signInButtonTapped(_ sender: UIButton) {
// TODO: Do some form validation on the email and password
if let email = emailTextField.text, let pass = passwordTextField.text {
// Check if it's sign in or register
if isSignIn {
// Sign in the user with Firebase
Auth.auth().signIn(withEmail: email, password: pass, completion: { (user, error) in
// Check that user isn't nil
if let u = user {
// User is found, go to home screen
self.ref = Database.database().reference()
self.ref?.child("users").observeSingleEvent(of: .value, with: {( snapshot) in
let value = snapshot.value as? NSDictionary
let username = value?["username"] as? String ?? ""
print ("*** " + username)
})
}
else {
// Error: check error and show message
}
})
}
Upvotes: 2
Views: 1636
Reputation: 3606
Since observeSingleEvent is an async call so it is running on the background thread, that is why it jumps on to the next bracket when you put a break point on self.ref, because it doesnt block the current thread of execution and does execute after sometime on background thread
One way to do is this:
@IBAction func signInButtonTapped(_ sender: UIButton) {
// TODO: Do some form validation on the email and password
if let email = emailTextField.text, let pass = passwordTextField.text {
// Check if it's sign in or register
if isSignIn {
// Sign in the user with Firebase
Auth.auth().signIn(withEmail: email, password: pass, completion: { (user, error) in
// Check that user isn't nil
if let u = user {
// User is found, go to home screen
self.fetchUserName { fetchedUserName in
print(fetchedUserName)
}
}
else {
// Error: check error and show message
}
})
}
func fetchUserName(completionHandler: @escaping (String) -> Void) {
self.ref = Database.database().reference()
self.ref?.child("users").observeSingleEvent(of: .value, with: {( snapshot) in
//let value = snapshot.value as? NSDictionary
if let value = snapshot.value as? [String: Any] {
print(value)
let username = value["username"] as? String ?? ""
print (username)
completionHandler(username)
}
})
}
Upvotes: 2