Swift Firebase-如何验证`PhoneAuthCredential`并保持用户当前使用其当前电子邮件uid登录

时间:2019-02-25 14:30:10

标签: ios swift firebase firebase-authentication

用户通过电子邮件身份验证登录我的应用程序。一旦进入,他们就可以浏览和搜索不同的事物。但是,如果用户要发布,则必须验证其电话号码(如果他们不想发布其电话号码,则没有必要)。

电话号码和短信处理工作正常,但是一旦我对PhoneAuthCredential进行身份验证,与用户当前登录的电子邮件相关联的uid就会替换为从电话凭据生成的uid。这会导致一个全新的用户位于应用程序内部的情况,因此他们无权访问其任何数据(与电子邮件中的uid相关联的任何数据)。

enter image description here

基本上Auth.auth().currentUser?.uid最初是电子邮件的uid,现在Auth.auth().currentUser?.uid将是电话的uid

如何验证PhoneAuthCredential并保持用户当前使用其当前电子邮件uid登录?

var emailUid: String? // a6UVVWWN4CeTCLwvkn...
var verificationId: String?
var phoneUid: String? // tUi502DnKlc19U14xSidP8

// 1. user signs into the app with their email address and their uid is a6UVVWWN4CeTCLwvkn...
Auth.auth().signIn(withEmail: emailTextField.text!, password: self.passwordTextField.text!, completion: { 
    (authDataResult: AuthDataResult?, error) in

    self.emailUid = authDataResult?.user.uid  // a6UVVWWN4CeTCLwvkn...         
})

// 2. user goes to post something but before they can post they have to verify their phone number
PhoneAuthProvider.provider().verifyPhoneNumber(phoneNumberTextfield.text!, uiDelegate: nil) {
    (verificationID, error) in

    guard let verificationID = verificationID else { return }

    self.verificationId = verificationID
}

// 3. sms code is sent to user's phone and they enter it
let credential = PhoneAuthProvider.provider().credential(withVerificationID: verificationId!, verificationCode: smsTextField.text!)

// 4. now VERIFY sms code by signing the user in with the PhoneAuthCredential
Auth.auth().signInAndRetrieveData(with: credential, completion: {
    (authDataResult, error) in

    self.phoneUid = authDataResult?.user.uid // tUi502DnKlc19U14xSidP8 this is now the current user's uid

    // 5. save phoneNumber and verificationId to the user's uid ref associated with the EMAIL address
    var dict = [String: Any]()
    dict.updateValue(verificationId!, forKey: "verificationId")
    dict.updateValue(phoneNumberTextfield.text!, forKey: "phoneNumber")
    dict.updateValue(self.phoneUid!, forKey: "phoneUid")

    if Auth.auth().currentUser!.uid == self.emailUid! {

        // THIS WILL NEVER RUN
        let emailUidRef = Database.database().reference().child("users").child(emailUid!)
        emailUidRef?.updateChildValues(dict)
    }
})

1 个答案:

答案 0 :(得分:0)

您可以使用Firebase Authentication's account linking将两个帐户链接在一起。如该文档所述:

  

完成新的身份验证提供程序的登录流程,直到(但不包括)调用FirebaseAuth.signInWith方法之一。

因此,您跳过signInAndRetrieveData(with: credential),而是致电User.linkAndRetrieveData(with: credential)。关联帐户后,您可以使用其中任何一个登录以获取“组合”身份验证用户。