为什么我的观察值函数从firebase数据库中检索数据第一次不起作用?

时间:2018-01-19 04:30:44

标签: ios swift firebase firebase-realtime-database firebase-authentication

我正在尝试使用Google帐户创建登录系统以进行firebase身份验证。

如果用户首次使用谷歌帐户登录,那么他们必须首先选择他们的城市住所才能转到HomeVC,否则他们可以直接进入homeVC。

要解决此问题,首先我尝试从firebase数据库中获取数据。如果用户之前已经登录过,那么他们将在我的firebase中拥有用户数据库。因此,来自snapshot.value的{​​{1}}的结果将存储到observe

如果用户第一次登录,那么userBasicInformation应为零。但我不知道为什么从我的firebase数据库中检索数据的代码行似乎永远不会在第一次执行

userBasicInformation

这是此登录系统的简化代码。我给出打印号码来跟踪代码。打印结果低于

Database.database().reference().child("users/\(userKM.uid)").reference().observe

这是调试区域的结果

  
      
  • 用户成功登录谷歌
  •   
  • 用户成功登录firebase
  •   
  • 1
  •   
  • 2
  •   
  • 5
  •   
  • 3
  •   

我不明白为什么'3'使用observe从'firebase数据库中检索数据'似乎永远不会先执行

我希望1 - > 2 - > 3 - > 5 , 但我得到了1 - > 2 - > 5 - > 3

这就是为什么import UIKit import Firebase import GoogleSignIn // variable that store user basic data (uid, fullname, email, domicile) var userBasicInformation : [String:Any]? // sign in using google account to Firebase Authenctication Auth.auth().signIn(with: credential) { (user, error) in if let error = error { print("failed to create firebase user using google account") print("\(error.localizedDescription)") return } print("user successfully logged into firebase") print("1") guard let userKM = user else { return } print("2") // retrieve User Basic data from firebase database Database.database().reference().child("users/\(userKM.uid)").reference().observe(.value, with: { (snapshot) in print("3") if let valueDictionary = snapshot.value as? [String:Any] { let userValue = User(dictionary: valueDictionary) let userInformation : [String:Any] = [ "uid" : userValue.uid, "fullname" : userValue.fullname, "email" : userValue.email, "domicile" : userValue.domicile ] userBasicInformation = userInformation } else { print("4") // if there is no snapshott.value (no database for certain uid) then set to nil. it means user logged in using gmail forthe first time userBasicInformation = nil } }) // if user has signed up before then send to mainTabBar (it means he/she has picked a city), otherwise pickCity first // if the user sign Up for the first time, then userBasicInformation will be nil because there is no user default available if userBasicInformation == nil { print("5") // save user data to Firebase Database let userX = User(uid: userKM.uid, fullname: userKM.displayName!, email: userKM.email!) userX.save(completion: { (error) in if error != nil { print(error!) } }) // assign Value to superGlobal Variable userBasicInformation = [ "uid" : userX.uid as Any, "fullname" : userX.fullname as Any, "email" : userX.email as Any, "domicile" : userX.domicile as Any ] self.pickCity() } else { print("6") self.goToMainTabBar() } } } 如果重新启动模拟器

总是为零

为什么我的观察值第一次不起作用?

1 个答案:

答案 0 :(得分:1)

很明显。

执行Database.database().reference().child("users/\(userKM.uid)").reference().observe(.value, with: { (snapshot) in

是异步操作,它将在您的请求响应后执行

当你

检查该异步块if userBasicInformation == nil {旁边的child("users/\(userKM.uid)")条件,因此它将首先执行。 (它不会等待你的firebase请求child("users/\(userKM.uid)")完成)

解决此问题将所有if userBasicInformation == nil {else块放入您的firebase请求块中。

希望它对你有所帮助

修改\ UPDATE

我不明白为什么在把这些东西放进if userBasicInformation == nil {之后你正在检查users/\(userKM.uid)"你不需要检查它是否为零

如果你不想让用户自动登录,那么

viewDidLoad put

  GIDSignIn.sharedInstance().signInSilently()

    Auth.auth().addStateDidChangeListener { (auth, user) in
        if user != nil {
         // HERE YOU CAN  PERFORM ANYTHING LIKE SAVING TO USERDEFAULT OR ANYTHING AFTER USER LOGGED IN
            UserDefaults.standard.setValue(user?.uid, forKeyPath: "uid")

            self.performSegue(withIdentifier: "CurrentlyLoggedIn", sender: nil)

        }
    }