苹果登录导致FIRAuthErrorUserInfoNameKey=ERROR_EMAIL_ALREADY_IN_USE(代码=17007) [英] Apple sign in causes FIRAuthErrorUserInfoNameKey=ERROR_EMAIL_ALREADY_IN_USE (Code = 17007)

本文介绍了苹果登录导致FIRAuthErrorUserInfoNameKey=ERROR_EMAIL_ALREADY_IN_USE(代码=17007)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用SwiftUI、Xcode12.5.1、Swift5.4.2、iOS14.7.1、

My Firebase-Email/Password登录页面应扩展为其他登录选项,例如Apple-Login(最终为Google-Login、Facebook-Login等)。

我的步骤:

  1. 使用电子邮件/密码登录到Firebase
  2. 注销
  3. 使用";登录使用Apple"; -->;则出现以下错误:
Error Domain=FIRAuthErrorDomain Code=17007

"The email address is already in use by another account."

UserInfo={NSLocalizedDescription=The email address is already in use by another account.,

FIRAuthErrorUserInfoNameKey=ERROR_EMAIL_ALREADY_IN_USE}

我打算做的是将现有的Email/Password-Firebase-帐户链接到Sign in with Apple-帐户(如herehere所述)。

但要做到这一点,我需要错误FIRAuthErrorUserInfoUpdatedCredentialKey,以便最终检索旧用户。

在我的例子中,我得到的是ERROR_EMAIL_ALREADY_IN_USE,它不会链接任何旧用户。

我必须做什么?

以下是我的代码:

let credential = OAuthProvider.credential(withProviderID: "apple.com", idToken: idTokenString, rawNonce: nonce)

Auth.auth().signIn(with: credential) { (authResult, error) in

    if (error != nil) {
        print(error?.localizedDescription as Any)
        return
    }
    print("signed in with Apple...")
    
    do {
        // if user did log in with Email/Password previously
        if let email = try THKeychain.getEmail(),
           let password = try THKeychain.getPassword() {

            let credential = EmailAuthProvider.credential(withEmail: email, password: password)

            if let user = authResult?.user {

                // here I am trying to link the existing Firebase-Email/Password account to the just signed-in with Apple account
                user.link(with: credential) { (result, linkError) in
                    
                    print(linkError)  // this is where I get FIRAuthErrorUserInfoNameKey=ERROR_EMAIL_ALREADY_IN_USE
                    
                    // unfortunately, the two accounts are not linked as expected due to this error !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

                    // What is missing ??????????????????
                    
                    loginStatus = true
                }
            }
        } else {
            loginStatus = true
        }
    } catch {
        print(error.localizedDescription)
    }
}

在Firebase文档上显示:

Sign in with Apple will not allow you to reuse an auth credential to link to an existing account. If you want to link a Sign in with Apple credential to another account, you must first attempt to link the accounts using the old Sign in with Apple credential and then examine the error returned to find a new credential. The new credential will be located in the error's userInfo dictionary and can be accessed via the FIRAuthErrorUserInfoUpdatedCredentialKey key.

如果您要将使用Apple Credential的登录链接到另一个帐户,则必须首先尝试使用旧的使用Apple Credential的登录链接帐户...这一部分的确切含义是什么?什么是old Sign in with Apple credential

我该如何做?

事实上,在链接调用时,我实际上希望使用某种linkError.userInfo更新的用户进行登录。但我的示例中的linkError只给出了ERROR_EMAIL_ALREADY_IN_USE错误,而没有进一步的userInfo。

作为Peter Friese mentions in his Blog,我应该能够以某种方式从error.userInfo中检索AuthErrorUserInfoUpdatedCredentialKey。但在我的例子中,linkError没有任何类型的信息--不幸的是!

这里摘录了Peter的例子:(由于未知的原因,同样不适用于我的情况?)

currentUser.link(with: credential) { (result, error) in // (1)
    if let error = error, (error as NSError).code == AuthErrorCode.credentialAlreadyInUse.rawValue { // (2)
        print("The user you're signing in with has already been linked, signing in to the new user and migrating the anonymous users [(currentUser.uid)] tasks.")
        if let updatedCredential = (error as NSError).userInfo[AuthErrorUserInfoUpdatedCredentialKey] as? OAuthCredential {
            print("Signing in using the updated credentials")
            Auth.auth().signIn(with: updatedCredential) { (result, error) in
                if let user = result?.user {
                    // TODO: handle data migration
                    self.doSignIn(appleIDCredential: appleIDCredential, user: user) // (3)
                }
            }
        }
    }
}

推荐答案

颠倒链接顺序使我稍微前进了一点。

如果我按Sign in with Apple按钮,我的代码现在首先使用Firebase-Email/Password登录(即从钥匙串中获取必要的凭据)。在第二步,链接到苹果的凭据。通过这样做,链接最终在链接回调中为我提供了所需的AuthErrorUserInfoUpdatedCredentialKey

在那里我检索updatedCredential以登录Apple。

请参阅下面的代码。

然而,我还是不知道为什么这样登录后,我的数据仍然丢失?

此数据迁移步骤如何工作?

user.link(with: appleCredentials) { ... }不应该做这项工作吗?

我需要做什么才能获得完全相同的Firebase数据,无论使用何种登录方式?

let appleCredentials = OAuthProvider.credential(withProviderID: "apple.com", idToken: idTokenString, rawNonce: nonce)

do {
    // if user did log in with Email/Password anytime before
    if let email = try THKeychain.getEmail(),
       let password = try THKeychain.getPassword() {
        
        let firebaseEmailCredentials = EmailAuthProvider.credential(withEmail: email, password: password)
        
        Auth.auth().signIn(with: firebaseEmailCredentials) { (authResult, error) in
            
            if let user = authResult?.user {
                
                user.link(with: appleCredentials) { (result, linkError) in
                    
                    if let linkError = linkError, (linkError as NSError).code == AuthErrorCode.credentialAlreadyInUse.rawValue {
                        
                        print("The user you're signing in with has been linked.")
                        print("Signing in to Apple and migrating the email/pw-firebase-users [(user.uid)]` data.")
                        if let updatedCredential = (linkError as NSError).userInfo[AuthErrorUserInfoUpdatedCredentialKey] as? OAuthCredential {
                            
                            print("Signing in using the updated credentials")
                            Auth.auth().signIn(with: updatedCredential) { (result, error) in
                                if let _ = result?.user {
                                    print("signed in with Apple...")
                                    // TODO: handle data migration
                                    print("Data-migration takes place now...")
                                    
                                    loginStatus = true
                                }
                            }
                        }
                    }
                    else if let error = error {
                        print("Error trying to link user: (error.localizedDescription)")
                    }
                    else {
                        if let _ = result?.user {
                            loginStatus = true
                        }
                    }
                }
            }
        }
    } else {
        // case where user never logged in with firebase-Email/Password before
        Auth.auth().signIn(with: appleCredentials) { (result, error) in
            if let _ = result?.user {
                print("signed in with Apple...")
                loginStatus = true
            }
        }
    }
} catch {
    print(error.localizedDescription)
}

这篇关于苹果登录导致FIRAuthErrorUserInfoNameKey=ERROR_EMAIL_ALREADY_IN_USE(代码=17007)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆