我使用Firebase的电子邮件/密码登录方法为用户创建帐户。使用该方法,用户必须拥有一个电子邮件地址才能通过Firebase进行身份验证。
FirebaseAuth有一个名为FIRUser
的User
对象
当用户首次创建帐户或登录回调中的现有帐户时,User
对象将被初始化:
创建帐号:
Auth.auth().createUser(withEmail: emailTextField.text!, password: passwordTextField.text!, completion: {
(user, error) in
// user's auth credentials are now created but user can still be nil
登录现有帐户:
Auth.auth().signIn(withEmail: self.emailTextField.text!, password: self.passwordTextField.text!, completion: {
(user, error) in
// user's auth credentials are now accessed but user can still be nil
User
对象有一个.email
可选的String类型,包含用户的电子邮件地址。
我使用单例类来管理通过Firebase发生的所有事情,在上面的两种情况下,当User
对象被初始化时,我将数据传递给我的Firebase单例的类属性。我知道User对象可以返回为nil所以我运行if-let
以确保它不是。
我的问题是如果使用电子邮件/密码登录方法如果User
对象在回调中不是nil,那么.email
可能是零,即使有必要让它创建一个帐户或登录?
在我运行if-let
语句之后,我使用guard
语句检查并查看.email
是否不是nil但似乎它可以在FirebaseSingleton属性初始化之前运行(这意味着它将为nil)或者它可能是不必要的保证User对象返回一个值。
顺便说两下,用户创建和帐户或登录emailTextFiled并且passwordTextField不会是nil。我运行空格,.isEmpty和!= nil检查它们。
我的代码:
class FirebaseSingleton{
static let sharedInstance = FirebaseSingleton()
var dbRef: DatabaseReference? = Database.database().reference()
var storageDbRef: StorageReference? = Storage.storage().reference(forURL: "gs://blablabla.appspot.com")
var currentUser: User? = Auth.auth().currentUser
var currentUserID: String? = Auth.auth().currentUser?.uid
var currentUserEmail: String? = Auth.auth().currentUser?.email
var currentUserPhotoUrl: URL? = Auth.auth().currentUser?.photoURL
var currentUserDisplayName: String? = Auth.auth().currentUser?.displayName
}
创建帐户:
Auth.auth().createUser(withEmail: emailTextField.text!, password: passwordTextField.text!, completion: {
(user, error) in
if error != nil { return }
if let user = user{
let sharedInstance = FirebaseSingleton.sharedInstance
sharedInstance.currentUser = user
sharedInstance.currentUserID = user.uid
sharedInstance.currentUserEmail = user.email // at this point is it possible for this to be nil?
sharedInstance.currentUserPhotoUrl = user.photoURL
sharedInstance.currentUserDisplayName = user.displayName
}else{
return
}
// is this guard statement necessary?
guard let email = user.uid else { return }
})
登录现有帐户:
Auth.auth().signIn(withEmail: emailTextField.text!, password: passwordTextField.text!, completion: {
(user, error) in
if error != nil { return }
if let user = user{
let sharedInstance = FirebaseSingleton.sharedInstance
sharedInstance.currentUser = user
sharedInstance.currentUserID = user.uid
sharedInstance.currentUserEmail = user.email // at this point is it possible for this to be nil?
sharedInstance.currentUserPhotoUrl = user.photoURL
sharedInstance.currentUserDisplayName = user.displayName
}else{
return
}
// is this guard statements necessary?
guard let email = user.uid else { return }
})
不确定你究竟要求什么(因为对我来说看起来更像是一个快速问题而不是firebase问题),但只要用户不是nil,uid
属性就不是可选的(String
)所以user.uid将永远不会是零。这是一个String?
的电子邮件是不一样的因此可能或不是nil
在与@Benjamin Jimenez和@kbunarjo建议进行了一次调情后,我做了一些思考,并意识到Firebase还有一个电话登录方法。如果它已启用且用户选择它作为其登录方法,那么.email
地址将为零,因为没有用于创建帐户的电子邮件地址。
对于我的情况,因为我使用电子邮件/密码登录方法,然后.email
不应该是零,因为它是创建帐户的唯一方法。但正如用户可以在完成处理程序中返回nil(即使使用正确的电子邮件和密码),也许电子邮件地址也可以返回为零,因为它是可选的。
据说最安全的方法是另一个if-let来检查user.email
是不是nil,如果出于某种奇怪的原因,那么它就是使用输入到emailTextField中的电子邮件地址作为替代。输入emailTextField和密码组合的电子邮件地址必须正确,否则用户将无法通过Firebase进行身份验证并输出错误!= nil。
Auth.auth().signIn(withEmail: emailTextField.text!, password: passwordTextField.text!, completion: {
(user, error) in
// if the email address and/or password are incorrect then error != nil and the code below this wont run
if error != nil { return }
if let user = user{
let sharedInstance = FirebaseSingleton.sharedInstance
sharedInstance.currentUser = user
sharedInstance.currentUserID = user.uid
sharedInstance.currentUserPhotoUrl = user.photoURL
sharedInstance.currentUserDisplayName = user.displayName
// instead of the guard statement I use another ‘if-let’ if for some reason .email is nil
if let currentUserEmail = user.email {
sharedInstance.currentUserEmail = currentUserEmail
}else{
sharedInstance.currentUserEmail = self.emailTextField.text! // the email address entered into here has to be valid otherwise it would've never made it to this point
}
}else{
return
}
})
如果创建帐户,请使用相同的确切代码进行回调
由于@rMickeyD注意到Facebook登录方法也不会使用电子邮件地址。我从来没用过它所以我没有把它包括在内。基本上,如果其他登录方法都没有使用您的电子邮件地址,那么user.email将为零。即使我有匿名登录作为选项,使用匿名登录的方法也不需要电子邮件地址或密码,因此可以理解电子邮件将是零。
您应该检查文档以查看是否需要该电子邮件以用于所有其他登录方法,但电话号码不需要它。