I'm trying to sign up users with Firebase auth. When a user signs up, I'd like them to be added to my Users
collection in Firestore as well as the Users
authorization section.
我正在尝试使用Firebase身份验证来注册用户。当用户注册时,我希望将它们添加到Firestore中的Users集合以及Users授权部分。
The createUser(withEmail: ...)
method works every time. However, my db.collection("users").document(user.id).setData([..]
method will only be called if I press the sign up button twice, and at that point the createUser(withEmail ...)
method gets called again. Here's the relevant code
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 help is greatly appreciated! Thank you all in advance
任何帮助是极大的赞赏!谢谢大家
1 个解决方案
#1
0
I've resolved the error. I ended up nesting the second network call in order to:
我已经解决了这个错误。我最终嵌套了第二个网络呼叫,以便:
-
Get the uid from the firestore who was authenticated
从经过身份验证的firestore获取uid
-
Not break firestore rules about writing to the database w/o an authorized uid
不要破坏关于使用授权的uid写入数据库的firestore规则
My UsersHelper.swift
file now looks like
我的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 {
// there was an error?
print("Error: \(result)")
signupError = result as? Error
} else {
// Got the user
firebaseUser = result as? Firebase.User
// Create user entry in DB
user.ID = firebaseUser!.uid
self.usersDataModel.create(user: user) { err in
// Completion handler
if let err = err as? Error {
dbError = err
}
userDispatchGroup.leave()
print("Done")
}
}
}
userDispatchGroup.notify(queue: .main) {
print("!dispatch group completed successfully")
if (signupError == nil && dbError == nil) {
completion(firebaseUser)
} else {
signupError != nil ? completion(signupError) : completion(dbError)
}
}
}
#1
0
I've resolved the error. I ended up nesting the second network call in order to:
我已经解决了这个错误。我最终嵌套了第二个网络呼叫,以便:
-
Get the uid from the firestore who was authenticated
从经过身份验证的firestore获取uid
-
Not break firestore rules about writing to the database w/o an authorized uid
不要破坏关于使用授权的uid写入数据库的firestore规则
My UsersHelper.swift
file now looks like
我的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 {
// there was an error?
print("Error: \(result)")
signupError = result as? Error
} else {
// Got the user
firebaseUser = result as? Firebase.User
// Create user entry in DB
user.ID = firebaseUser!.uid
self.usersDataModel.create(user: user) { err in
// Completion handler
if let err = err as? Error {
dbError = err
}
userDispatchGroup.leave()
print("Done")
}
}
}
userDispatchGroup.notify(queue: .main) {
print("!dispatch group completed successfully")
if (signupError == nil && dbError == nil) {
completion(firebaseUser)
} else {
signupError != nil ? completion(signupError) : completion(dbError)
}
}
}