gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-28 15:06:45 25 4
gpt4 key购买 nike

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

如果用户第一次使用google账号登录,那么在进入HomeVC前必须先选择所在城市,否则可以直接进入homeVC。

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

如果用户是第一次登录,那么 userBasicInformation 应该是 nil。但我不知道为什么从我的 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()
}
}
}

这是我调试区的结果

  • user successfully signin into google
  • user successfully logged into firebase
  • 1
  • 2
  • 5
  • 3

我不明白为什么使用 observe 的“从 firebase 数据库检索数据”的“3”似乎从来没有被首先执行

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

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

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

最佳答案

很明显。

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

是异步操作,它会在你的请求得到响应后执行

当你在的时候

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

修复此问题将所有 if userBasicInformation == nil {else block 放入您的 firebase 请求 block 中。

希望对你有帮助

编辑\更新

我不明白为什么在将这些东西放入 users/\(userKM.uid)" 之后检查 if userBasicInformation == 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)

}
}

关于ios - 为什么我的用于从 firebase 数据库检索数据的观察值函数第一次不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48334135/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com