Firebase身份验证重复凭据错误,苹果登录

huangapple go评论59阅读模式
英文:

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 = &quot;No current user found&quot;;
    Firebase.Auth.Credential credential = Firebase.Auth.OAuthProvider.GetCredential(&quot;apple.com&quot;, appleIdToken, rawNonce, null);

    auth.SignInAndRetrieveDataWithCredentialAsync(credential)
    .ContinueWith(task =&gt; {
      if (task.IsCanceled) 
      {
      Debug.LogError(&quot;BB 1 SignInAndRetrieveDataWithCredentialAsync was canceled.&quot;);

        return;
      }
      if (task.IsFaulted) {
        Debug.LogError(&quot;BB 2 SignInAndRetrieveDataWithCredentialAsync encountered an error: &quot; + task.Exception);
    
        return;
      }
    
     Firebase.Auth.SignInResult result = task.Result;
                resultText.text = &quot;User signed in successfully : &quot; + 
     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 = &quot;User signed out&quot;;
}

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.)) ---&gt; System.AggregateException: One or more errors occurred. (Duplicate credential received. Please try again with a new credential.) ---&gt; Firebase.FirebaseException: Duplicate credential received. Please try again with a new credential.
   --- End of inner exception stack trace ---
   --- End of inner exception stack trace ---
---&gt; (Inner Exception #0) System.AggregateException: One or more errors occurred. (Duplicate credential received. Please try again with a new credential.) ---&gt; Firebase.FirebaseException: Duplicate credential received. Please try again with a new credential.
   --- End of inner exception stack trace ---
---&gt; (Inner Exception #0) Firebase.FirebaseException: Duplicate credential received. Please try again with a new credential.&lt;---
&lt;---
&lt;&gt;c__DisplayClass33_0:&lt;SignInWithAppleSuccessful&gt;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&amp;)
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 🥲

huangapple
  • 本文由 发表于 2023年7月12日 21:42:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/76671251.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定