英文:
Firebase Authentication Duplicate Credential Error, Apple Sign In
问题
我正在开发一个游戏,需要在不考虑操作系统类型的情况下在设备之间传输数据。我已经从Unity Asset Store导入了Apple Sign In Asset 和 Firebase身份验证包到我的项目中。
苹果登录和使用苹果作为提供程序的Firebase身份验证正常工作,我可以在使用我的Apple ID登录后从游戏中读取和写入数据库中的数据。
但是,当我尝试从Firebase身份验证中注销并再次使用相同的登录方法登录时,我会收到重复凭据错误。
以下是我在成功进行苹果登录后进行用户身份验证的方式。
private void SignInWithAppleSuccessful()
{
auth = Firebase.Auth.FirebaseAuth.DefaultInstance;
var appleIdToken = PlayerPrefs.GetString(AppleUserTokenKey);
var rawNonce = Guid.NewGuid().ToString();
var user = auth.CurrentUser;
if (auth.CurrentUser != null)
{
userId.text = user.UserId;
AuthenticationSuccessful(auth.CurrentUser);
AddListenersToDatabase();
}
else
{
resultText.text = "No current user found";
Firebase.Auth.Credential credential = Firebase.Auth.OAuthProvider.GetCredential("apple.com", appleIdToken, rawNonce, null);
auth.SignInAndRetrieveDataWithCredentialAsync(credential)
.ContinueWith(task => {
if (task.IsCanceled)
{
Debug.LogError("BB 1 SignInAndRetrieveDataWithCredentialAsync was canceled.");
return;
}
if (task.IsFaulted) {
Debug.LogError("BB 2 SignInAndRetrieveDataWithCredentialAsync encountered an error: " + task.Exception);
return;
}
Firebase.Auth.SignInResult result = task.Result;
resultText.text = "User signed in successfully: " +
result.User.UserId;
userId.text = result.User.UserId;
AuthenticationSuccessful(result.User);
AddListenersToDatabase();
}
}
}
Google文档提到Firebase身份验证令牌具有长期有效性。这意味着它们会在某个时候过期吗?
为了模拟令牌过期,我将注销方法添加到我的项目中。
if (auth.CurrentUser != null)
{
auth.SignOut();
RemoveListenerFromDatabase();
resultText.text = "User signed out";
}
在注销后,我尝试使用相同的方法SignInWithAppleSuccessful()
重新登录,但收到以下错误消息:
SignInAndRetrieveDataWithCredentialAsync encountered an error: System.AggregateException: One or more errors occurred. (Duplicate credential received. Please try again with a new credential.) ---> System.AggregateException: One or more errors occurred. (Duplicate credential received. Please try again with a new credential.) ---> Firebase.FirebaseException: Duplicate credential received. Please try again with a new credential.
--- End of inner exception stack trace ---
--- End of inner exception stack trace ---
---> (Inner Exception #0) System.AggregateException: One or more errors occurred. (Duplicate credential received. Please try again with a new credential.) ---> Firebase.FirebaseException: Duplicate credential received. Please try again with a new credential.
--- End of inner exception stack trace ---
---> (Inner Exception #0) Firebase.FirebaseException: Duplicate credential received. Please try again with a new credential.<---
<---
<>.c__DisplayClass33_0:<SignInWithAppleSuccessful>b__0(Task`1)
System.Threading.Tasks.ContinuationTaskFromResultTask`1:InnerInvoke()
System.Threading.Tasks.Task:Execute()
System.Threading.ExecutionContext:RunInternal(ExecutionContext, ContextCallback, Object, Boolean)
System.Threading.Tasks.Task:ExecuteWithThreadLocal(Task&)
System.Threading.Tasks.Task:ExecuteEntry(Boolean)
System.Threading.ThreadPoolWorkQueue:Dispatch()
我已经尝试为每次登录尝试生成新的Nonce字符串,但仍然收到相同的错误消息。
英文:
I am working on a game where i need to transfer data between devices, regardless of OS type. I have imported the Apple Sign In Asset from Unity Asset Store and Firebase Authentication package to my project.
Apple Sign-In and Firebase Authentication using apple as a provider is working, i am able to read and write data to my database from my game after signing in with my Apple ID.
However, when I try to sign out from Firebase authentication and sign back in using the same sing in method i get the duplicate credential error.
This is how i am authenticating the user after a successful Apple Sign-In.
private void SignInWithAppleSuccessful()
{
auth = Firebase.Auth.FirebaseAuth.DefaultInstance;
var appleIdToken = PlayerPrefs.GetString(AppleUserTokenKey);
var rawNonce = Guid.NewGuid().ToString();
var user = auth.CurrentUser;
if (auth.CurrentUser != null)
{
userId.text = user.UserId;
AuthenticationSuccessful(auth.CurrentUser);
AddListenersToDatabase();
}
else
{
resultText.text = "No current user found";
Firebase.Auth.Credential credential = Firebase.Auth.OAuthProvider.GetCredential("apple.com", appleIdToken, rawNonce, null);
auth.SignInAndRetrieveDataWithCredentialAsync(credential)
.ContinueWith(task => {
if (task.IsCanceled)
{
Debug.LogError("BB 1 SignInAndRetrieveDataWithCredentialAsync was canceled.");
return;
}
if (task.IsFaulted) {
Debug.LogError("BB 2 SignInAndRetrieveDataWithCredentialAsync encountered an error: " + task.Exception);
return;
}
Firebase.Auth.SignInResult result = task.Result;
resultText.text = "User signed in successfully : " +
result.User.UserId;
userId.text = result.User.UserId;
AuthenticationSuccessful(result.User);
AddListenersToDatabase();
}
}
Google document mentions that Firebase Authentication tokens are long lived. Meaning it will expire at some point?
In order to simulate token expiration i added sign out method to my project.
if (auth.CurrentUser != null)
{
auth.SignOut();
RemoveListenerFromDatabase();
resultText.text = "User signed out";
}
After signing out, i then tried to sign back in using the same method above SignInWithAppleSuccessful()
And received the following error
SignInAndRetrieveDataWithCredentialAsync encountered an error: System.AggregateException: One or more errors occurred. (One or more errors occurred. (Duplicate credential received. Please try again with a new credential.)) ---> System.AggregateException: One or more errors occurred. (Duplicate credential received. Please try again with a new credential.) ---> Firebase.FirebaseException: Duplicate credential received. Please try again with a new credential.
--- End of inner exception stack trace ---
--- End of inner exception stack trace ---
---> (Inner Exception #0) System.AggregateException: One or more errors occurred. (Duplicate credential received. Please try again with a new credential.) ---> Firebase.FirebaseException: Duplicate credential received. Please try again with a new credential.
--- End of inner exception stack trace ---
---> (Inner Exception #0) Firebase.FirebaseException: Duplicate credential received. Please try again with a new credential.<---
<---
<>c__DisplayClass33_0:<SignInWithAppleSuccessful>b__0(Task`1)
System.Threading.Tasks.ContinuationTaskFromResultTask`1:InnerInvoke()
System.Threading.Tasks.Task:Execute()
System.Threading.ExecutionContext:RunInternal(ExecutionContext, ContextCallback, Object, Boolean)
System.Threading.Tasks.Task:ExecuteWithThreadLocal(Task&)
System.Threading.Tasks.Task:ExecuteEntry(Boolean)
System.Threading.ThreadPoolWorkQueue:Dispatch()
I have tried generating new Nonce string for every sign in attempt and nothing changed. Still get the same error message.
答案1
得分: 1
我通过删除在PlayerPrefs中保存的Apple用户ID和Apple用户令牌来解决了这个问题。这样会重新显示Apple登录提示,但现在我可以重新对同一用户进行身份验证。
起初,我以为每次使用Apple登录时都会获得相同的Apple用户令牌,但事实证明并非如此。每次用户使用Apple登录时,都会返回一个新的Apple用户令牌。我不再遇到重复凭据错误。
请注意,如果您从Firebase身份验证中注销,您需要删除您的令牌,并重新提示用户登录到您正在使用的任何提供程序,以获取新生成的令牌。
我在这个问题上花费了太多时间 😢
英文:
I solved the issue by deleting Apple user id and Apple user token which i saved in PlayerPrefs. It re-shows the Apple Sign In prompt but i am now able to re-authenticate the same user.
At first i thought i was getting the same Apple User Token for each Apple Sign In but turns out that wasn't the case. Every time a user signs in with Apple Sign In it returns a new Apple User Token. I am no longer getting duplicate credential errors.
Note that if you ever sign out from Firebase Authentication, you need to erase your tokens and re-prompt user to sign in to whichever provider you are using in order to get that newly generated token.
I have spent too much time on this 🥲
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论