Sign in after failed account linking with Apple not working

39 Views Asked by At

I am trying to sign in after failed account linking an anonymous account with Apple, but it is failing when I first try to link it and fallback to sign in. I have enabled debug logging and done manual debugging but it just fails silently. This works for Google.

let credential = OAuthProvider.credential(withProviderID: "apple.com",
                                            idToken: idTokenString,
                                            rawNonce: nonce)
Task {
    do {
        let result = try await user.link(with: credential)
        self.user = result.user
        return true
    }
    catch AuthErrorCode.credentialAlreadyInUse {
        try await Auth.auth().signIn(with: credential)
        return true
    }
}
1

There are 1 best solutions below

0
Daniel Wallman On

I found this code on GitHub that implies Apple credentials somehow would get invalidating when trying to link them. So I tried changing the code to

private let authLinkErrors: [AuthErrorCode.Code] = [
        .emailAlreadyInUse,
        .credentialAlreadyInUse,
        .providerAlreadyLinked
    ]

let credential = OAuthProvider.credential(withProviderID: "apple.com",
                                            idToken: idTokenString,
                                            rawNonce: nonce)
Task {
    do {
        let result = try await user.link(with: credential)
        self.user = result.user
        return true
    }
    catch {
        if let error = error as NSError? {
            if let code = AuthErrorCode.Code(rawValue: error.code),
                authLinkErrors.contains(code) {
                
                let appleCredentials =
                credential.provider == "apple.com"
                ? error.userInfo[AuthErrorUserInfoUpdatedCredentialKey] as? AuthCredential
                : nil
                
                try await Auth.auth().signIn(with: appleCredentials ?? credential)
                return true
            }
        }
        throw error
    }
}