下面是我的注册页面的代码。我要这样做,以便当有人在注册页面上创建帐户时,可以在用户集合中创建一个文档,并将uuid包含在该文档中。但是,session.session?.uid最终为nil。有人知道这是为什么吗?
struct SignUpView: View {
@State var email = ""
@State var password = ""
@State var name = ""
@State var error = ""
@EnvironmentObject var session: SessionStore
func signUp() {
let db = Firestore.firestore()
let user = db.collection("users").document()
let test = db.collection("users").document(user.documentID).collection("routines").document()
session.signUp(email: email, password: password) { (result, error) in
if let error = error {
self.error = error.localizedDescription
print("This is the error \(error)")
return
} else {
self.email = ""
self.password = ""
}
}
user.setData(["id": user.documentID, "email": email]) { (err) in
if err != nil {
print((err?.localizedDescription)!)
return
}
}
print(session.session?.uid)
test.setData(["id:": test.documentID, "msg": "samwell Tarly", "uuid": session.session?.uid]) { (err) in
print("ummmmm test data?")
if err != nil {
print((err?.localizedDescription)!)
return
}
}
}
Firebase API是异步的,仅因为它们通过Internet访问远程系统会花费一些时间。顺便说一句,访问本地磁盘也是如此。 blog post对此进行了更详细的说明。
因此,session.signUp
是一个异步过程。即在print(session.session?.uid)
返回之前执行对session.signUp
的调用。因此,session.session?.uid
仍为nil
。
要解决此问题,您可以像这样嵌套呼叫:
session.signUp(email: email, password: password) { (result, error) in
if let error = error {
self.error = error.localizedDescription
print("This is the error \(error)")
return
}
else {
self.email = ""
self.password = ""
user.setData(["id": user.documentID, "email": email]) { (err) in
if err != nil {
print((err?.localizedDescription)!)
return
}
}
}
}
一般来说,我会[[强烈]]建议不要在视图中执行太多逻辑,而应尽可能使视图贫乏-意思是:将所有逻辑放入视图模型,并将视图绑定到视图使用合并的模型。这将使您的代码更加简洁,易于测试且易于维护。请参见https://peterfriese.dev/replicating-reminder-swiftui-firebase-part2/以了解如何执行此操作。