【发布时间】:2018-10-31 17:03:15
【问题描述】:
我正在尝试使用 Firebase 身份验证注册用户。当用户注册时,我希望将他们添加到我在 Firestore 中的 Users 集合以及 Users 授权部分。
createUser(withEmail: ...) 方法每次都有效。但是,我的db.collection("users").document(user.id).setData([..] 方法只有在我按下注册按钮两次时才会被调用,并且此时createUser(withEmail ...) 方法会再次被调用。这是相关代码
SignupViewController.swift
@IBAction func signupButtonTapped(_ sender: UIButton) {
// user: User() defined here
usersHelper.signup(user: user, password: password) { result in
// This closure is only executed on the second press
guard let user = result as? Firebase.User else {
let error = result as? Error
self.handleSignupError(error!)
return
}
self.performSegue(withIdentifier: "ShowGroupsFromSignupSegue", sender: self)
}
}
UsersHelper.Swift
func signup(user: User, password: String, completion: @escaping (_ result: Any?) -> Void) {
let userDispatchGroup = DispatchGroup()
var signupError: Error? = nil
var dbError: Error? = nil
var firebaseUser: Firebase.User? = nil
userDispatchGroup.enter()
usersDataModel.signupUser(user: user, password: password) { result in
// Completion handler
if result as? Error != nil {
signupError = result as? Error
} else {
// Got the user
firebaseUser = result as? Firebase.User
}
userDispatchGroup.leave()
}
userDispatchGroup.enter()
usersDataModel.create(user: user) { err in
// This will only execute if signUp is called twice
if let result = err as? Error {
print("Error msg: \(result.localizedDescription)")
dbError = result
}
print("!Created db user")
userDispatchGroup.leave()
}
userDispatchGroup.notify(queue: .main) {
print("!dispatch group completed successfully")
if (signupError == nil && dbError == nil) {
completion(firebaseUser)
} else {
signupError != nil ? completion(signupError) : completion(dbError)
}
}
}
UsersDataModel.swift
func signupUser(user: User, password: String, _ completion: @escaping (_ err: Any? ) -> Void) {
// Create user in Auth & create DB entry
Auth.auth().createUser(withEmail: user.email, password: password) { (authResult, err) in
if let err = err {
print("Error creating user \(err)")
completion(err)
} else {
print("User signed up successfully")
completion(authResult) // completion called with User
}
}
}
func create(user: User, _ completion: @escaping (_ result: Any?) -> Void) {
// userData dictionary created here
db.collection("users").document(user.ID).setData(userData) { err in
if let err = err {
print("There was an error creating the user \(err)")
completion(err)
} else {
print("!User created in db successfully!")
completion(nil)
}
}
}
非常感谢任何帮助!先谢谢大家了
【问题讨论】:
-
我不确定你的调度组为什么不工作,你应该使用调试器看看发生了什么。我会说有一个参数类型为
Any?的闭包不是很好。你的闭包应该接受一个成功和一个可选的Error参数,就像Auth.auth()一样。 -
create中的功能是否需要经过身份验证的用户,而您第一次调用它时没有? -
@Paulw11 我不这么认为 - 我的 Firestore 规则设置为允许所有人写入。但是当我只从
Auth.auth()的完成闭包中调用create()时,这些调用确实有效。我只是不想有这样的嵌套网络调用
标签: ios swift firebase asynchronous closures