firebase - Firebase SwiftUI and Firebase Auth - not reading user ID?
问题描述
Below is the code for my signup page. I want to make it so that when someone creates an account on the sign up page, I create a document in the users collection and include uuid in the document. However, session.session?.uid ends up being nil. Does anyone know why this is?
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
}
}
}
解决方案
The Firebase APIs are asynchronous, simply because they access a remote system, across the internet, which takes a little time. The same applies for accessing the local disk, by the way. This blog post explains this in more detail.
Consequently, session.signUp
is an asynchronous process. I.e. the call to print(session.session?.uid)
is executed before session.signUp
returns. Thus, session.session?.uid
is still nil
.
To work around this, you can nest your calls like this:
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
}
}
}
}
Generally speaking, I would strongly recommend to not perform so much logic in your views, but instead keep your views as anaemic as possible - meaning: put all your logic into view models, and bind the view to the view models by using Combine. This will make your code much cleaner, easier to test, and maintainable.
See https://peterfriese.dev/replicating-reminder-swiftui-firebase-part2/ for how to do this.
推荐阅读
- javascript - 过滤后的数组长度
- javascript - 可以向 angular cli 生成的脚本标签添加跨域属性吗?
- c# - 将刚体添加到对象 Unity3D 时出现问题
- python - 在一次热编码期间/之后,是否可以使用另一列的值而不是二进制标志?
- python - 添加第二个 LSTM 层时遇到问题“输入 0 与层 lstm_2 不兼容:预期 ndim=3,发现 ndim=2”
- python - 如果您没有很好的初始参数猜测,您如何获得 scipy curve_fit 以找到合理的结果?
- java - JavaFX - 执行 JavaFX WebView 示例代码时出现 java.lang.reflect.InvocationTargetException
- sql - 调整查询以解释 if 语句?
- c++ - Linux 内核事件:timeval 或 timespec
- utf-8 - 中文 Orbeon 表格返回问号