我如何创建用户帐户
这是我使用的一个例子。当用户提供凭据时,FirebaseAuth 会检查这些凭据是否可用于创建用户帐户。该函数返回两个值,一个表示创建是否成功的布尔值,一个可选的错误,当创建不成功时返回。如果布尔值返回 true,我们只需推送到下一个视图控制器。否则,我们会显示错误。
func createUserAcct(completion: @escaping (Bool, Error?) -> Void) {
//Try to create an account with the given credentials
Auth.auth().createUser(withEmail: emailTextField.text!, password: passwordConfirmTextField.text!) { (user, error) in
if error == nil {
//If the account is created without an error, then we will make a ProfileChangeRequest, i.e. update the user's photo and display name.
if let firebaseUser = Auth.auth().currentUser {
let changeRequest = firebaseUser.createProfileChangeRequest()
//If you have a URL for FirebaseStorage where the user has uploaded a profile picture, you'll pass the url here
changeRequest.photoURL = URL(string: "nil")
changeRequest.displayName = self.nameTextField.text!
changeRequest.commitChanges { error in
if let error = error {
// An error happened.
completion(false, error)
} else {
//If the change is committed successfully, then I create an object from the credentials. I store this object both on the FirebaseDatabase (so it is accessible by other users) and in my user defaults (so that the user doesn't have to remotely grab their own info
//Create the object
let userData = ["email" : self.emailTextField.text!,"name": self.nameTextField.text!] as [String : Any]
//Store the object in FirebaseDatabase
Database.database().reference().child("Users").child(firebaseUser.uid).updateChildvalues(userData)
//Store the object as data in my user defaults
let data = NSKeyedArchiver.archivedData(withRootObject: userData)
UserDefaults.standard.set(data, forKey: "UserData")
UserDefaults.standard.set([Data](), forKey: "UserPhotos")
completion(true, nil)
}
}
}
} else {
// An error happened.
completion(false, error)
}
}
}
这是我如何使用它的示例。我们可以使用返回的成功布尔值来确定我们是否应该推送到下一个视图控制器,或者向用户显示错误警报。
createUserAcct { success, error in
//Handle the success
if success {
//Instantiate nextViewController
let storyboard = UIStoryboard(name: "Main", bundle: .main)
let nextVC = storyboard.instantiateViewController(withIdentifier: "NextVC") as! NextViewController
//Push typeSelectVC
self.navigationController!.pushViewController(viewController: nextVC, animated: true, completion: {
//We are no longer doing asynchronous work, so we hide our activity indicator
self.activityIndicator.isHidden = true
self.activityIndicator.stopAnimating()
})
} else {
//We now handle the error
//We are no longer doing asynchronous work, so we hide our activity indicator
self.activityIndicator.isHidden = true
self.activityIndicator.stopAnimating()
//Create a UIAlertController with the error received as the message (ex. "A user with this email already exists.")
let alertController = UIAlertController(title: "Error", message: error!.localizedDescription, style: .alert)
let ok = UIAlertAction(title: "OK", style: .cancel, action: nil)
//Present the UIAlertController
alertController.addAction(ok)
self.present(alertController, animated: true, completion: nil)
}
}
如果这一切都有意义,请告诉我,我知道其中有很多。我只是在考虑你可能会发现你需要完成但你可能不知道的事情(比如提出更改请求,或在 FirebaseDatabase 上存储数据对象)。
现在检查电子邮件是否已被占用:
还记得我说过我在创建帐户时将用户对象发布到FirebaseDatabase 吗?好吧,我们可以查询给定的电子邮件以查看它是否已经存在。如果没有,我们将继续正常流程,而无需实际创建帐户。否则,我们只是告诉用户选择另一个电子邮件地址。
将用户对象推送到您的数据库(取自上述代码):
if let firebaseUser = Auth.auth().currentUser {
//Create the object
let userData = ["email" : self.emailTextField.text!,"name": self.nameTextField.text!] as [String : Any]
//Store the object in FirebaseDatabase
Database.database().reference().child("Users").child(firebaseUser.uid).updateChildvalues(userData)
}
现在查询是否有人已经拥有该电子邮件:
func checkIfEmailExists(email: String, completion: @escaping (Bool) -> Void ) {
Database.database().reference().child("Users").queryOrdered(byChild: "email").queryEqual(toValue: email).observeSingleEvent(of: .value, with: {(snapshot: DataSnapshot) in
if let result = snapshot.value as? [String:[String:Any]] {
completion(true)
} else {
completion(false)
}
}
}
那么我们可以这样称呼它:
checkIfEmailExists(email: emailTextField.text!, completion: {(exists) in
if exists {
//Present error that the email is already used
} else {
//Segue to next view controller
}
})