【问题标题】:why my observe value function to retrieve data from firebase database doesn't work for the first time?为什么我从 firebase 数据库中检索数据的观察值函数第一次不起作用?
【发布时间】:2023-03-17 20:14:01
【问题描述】:

我正在尝试使用 google 帐户创建一个登录系统来进行 firebase 身份验证。

如果用户第一次登录,则必须先选择所在城市再去HomeVC,否则可以直接去homeVC。

为了解决这个问题,我首先尝试从 firebase 数据库中获取数据。如果用户之前登录过,那么他们将在我的 Firebase 中拥有用户数据库。所以,snapshot.valueobserve 的结果将存储到 userBasicInformation

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

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

这里是这个登录系统的简化代码。我提供打印号码以跟踪代码。打印结果如下

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()
            }         
        }        
    }

这是我调试区的结果

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

我不明白为什么使用观察“从 firebase 数据库检索数据”的“3”似乎永远不会首先执行

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

这就是为什么如果我重新启动模拟器,userBasicInformation 总是为零

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

【问题讨论】:

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


    【解决方案1】:

    很明显。

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

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

    当你在时

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

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

    希望对你有帮助

    编辑\更新

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

    如果你不想让用户在他之前自动登录

    viewDidLoad

      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)
    
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多