0

Android 5.5.3f1、Google Playサービス、Firebase Unity SDK(認証、データベース、およびアナリティクス)を使用しています。 GPSを使ってユーザーを認証し、トークンを取得し、FirebaseのGoogle-In認証に使用する必要があります。次にFirebase Databaseを使ってプレイヤーの進行状況を同期させます。私は、次のデータベースの規則を使用しています:Unity Firebaseデータベースで認証の成功が​​表示されない場合があります

{ 
 
    "rules": { 
 
    "users": { 
 
     "$uid": { 
 
     ".read": "auth != null && auth.uid == $uid", 
 
     ".write": "auth != null && auth.uid == $uid" 
 
     } 
 
    } 
 
    } 
 
}

すべては、私が読んしようとしたとき、私は「Permission denied」エラーが取得しています(ほとんどは最初の数の試みに)たまにうまくいっているが、か私は非常にユーザーが認証され、彼のIDが彼が読み書きしようとしているノードと等しいと確信していますが、データベースに書き込みます。 私は人工的な遅延(最大5秒)を追加しようとしましたが、最初の失敗後に数回再試行しようとしましたが、まだ運がありません。認証とデータベース要求の進行を制御するために、私はContinueWithの代わりにCoroutinesを使用していますが、違いはないと思います(ContinueWithも試しました)

私は今使っているデータベースからプレイヤーの再生時間を取得する:

public IEnumerator CheckPlayedTime() 
 
     { 
 
      Debug.Log("Database : Start CheckingPlayedTime"); 
 
      if (currentUser == null || rootReference == null) 
 
      { 
 
       Debug.Log("Database : Can't get timedPlayedInSeconds! CurrentUser or Reference == null!"); 
 
       yield break; 
 
      } 
 

 
      var task = currentUserNode.Child("fullProgress").Child("timePlayedInSeconds").GetValueAsync(); 
 
      yield return new WaitUntil(() => task.IsCompleted || task.IsFaulted); 
 

 
      if (task.IsFaulted) 
 
      { 
 
       Debug.LogErrorFormat("Database : Can't get timedPlayedInSeconds! {0}", 
 
        task.Exception.InnerExceptions); 
 
      } 
 
      else if (task.IsCompleted) 
 
      { 
 
       if (task.Result.Exists) 
 
       { 
 
        long resultPlayedTime = (long) task.Result.GetValue(false); 
 

 
        Debug.Log("Database : Played Time Gotten" + resultPlayedTime); 
 
        playedTime = (int) resultPlayedTime; 
 
       } 
 
       else 
 
       { 
 
        Debug.Log("Database : PlayedTimeNotFound! Will be sent"); 
 
        playedTime = 0; 
 
       } 
 
      } 
 
     }

は、Googleのプレイサービス、firebase認証、およびデータベースとのすべてのアクションのシーケンスを見ることができ、コードセクションがあります。すべてが厳密に連続して実行されています。前の操作が完了するまで何も開始しません。上記のエラーを投げる最初の方法。これは "CheckPlayedTime"という名前です。

public IEnumerator Authorize(string googleIdToken) 
 
     { 
 
      FirebaseAuth auth = FirebaseAuth.DefaultInstance; 
 
      Credential credential = GoogleAuthProvider.GetCredential(googleIdToken, null); 
 

 
      //Starting of authorization with a gotten user's token 
 
      var task = auth.SignInWithCredentialAsync(credential); 
 
      yield return new WaitUntil(() => task.IsCompleted || task.IsFaulted || task.IsCanceled); 
 
      //Waiting for end of authentication 
 

 
      if (task.IsCanceled) 
 
      { 
 
#if DEBUG 
 
       DebugControlled.Log("AuthMethods : SignInWithCredentialAsync was canceled."); 
 
#endif 
 
      } 
 
      else if (task.IsFaulted) 
 
      { 
 
#if DEBUG 
 
       DebugControlled.Log("AuthMethods : SignInWithCredentialAsync encountered an error: " + task.Exception); 
 
#endif 
 
      } 
 
      else if (task.IsCompleted) 
 
      { 
 
       currentUser = task.Result;//Getting a current user 
 
       if (rootReference != null)//And a his own node in database 
 
        currentUserNode = rootReference.Child("users").Child(currentUser.UserId); 
 

 
#if DEBUG 
 
       DebugControlled.Log(string.Format("AuthMethods : User signed in successfully: {0} ({1})", 
 
        currentUser.DisplayName, currentUser.UserId)); 
 
#endif 
 
      } 
 
     }

IEnumerator Start() { 
 
    yield 
 
    return new WaitForSecondsRealtime(delayBetweenOperations); //Искусственная задержка 
 
    GooglePlayServicesSystem.instance.Authenticate(); //Делаем попытку авторизации в Google Play Services 
 

 
    yield 
 
    return new WaitUntil(() => GooglePlayServicesSystem.instance.AuthenticationTrialEnded); //Дожидаемся завершения 
 

 
    if (GooglePlayServicesSystem.instance.isAuthorized) //Если авторизация прошла успешно 
 
    { 
 
    yield 
 
    return new WaitForSecondsRealtime(delayBetweenOperations); //Искусственная задержка 
 
    var token = GooglePlayServicesSystem.instance.AuthenticationToken; //Получаем токен пользователя 
 
    yield 
 
    return StartCoroutine(FirebaseSystem.instance.Authorize(token)); //Начинаем и дожидаемся окончания авторизации в Firebase 
 

 
    int playedTime = -1; //Сюда будем записывать сыграное время 
 
    while (playedTime == -1 && attemptsCount < 3) //Повторные попытки получить доступ к данным (если playedTime все еще -1, значит доступ не был получен, пробуем еще) 
 
    { 
 
     yield 
 
     return new WaitForSecondsRealtime(delayBetweenOperations); //Искусственная задержка 
 
     yield 
 
     return StartCoroutine(FirebaseSystem.instance.CheckPlayedTime()); //Начинаем и дожидаемся запроса получения сыгранного времени 
 
     playedTime = FirebaseSystem.instance.playedTime; //Получаем сыгранное время 
 
     attemptsCount++; 
 
    } 
 

 
    yield 
 
    return StartCoroutine(ProgressSystem.instance.ComparePlayedTime(playedTime)); //Запускаем сравнение времени игры в локальном прогрессе и в базе данных Firebase 
 
    //Если локальное время меньше - запустится загрузка прогресса из базы данных Firebase 
 
    //Если локальнео время больше или не было получено время из базы данных (к примеру его там еще нет) - выполняется отправка прогресса в базу данных 
 
    } 
 

 
    var loadingOperation = SceneManager.LoadSceneAsync("MainLoading"); //После завершения всех операций - загружаем сцену главной загрузки игры 
 
}

認証とデータベースへのアクセス( "CheckPlayedTime")の第一審を再生するだけでGoogleの間を走るFirebase認証方法があります

もう一度 - うまくいきますが、必ずしもそうではありません。認証のために正しいトークンを得るたびに、firebase認証を完了し、適切なユーザーIDを取得するたびに。しかし、データベースの直後にはデータベース自体にアクセスすることはできませんが、ユーザーは確実に正しく認証され、アクセス権が必要です。私は困惑し、それがどのように可能か理解していない。誰でもここで何が起こっているのか分かりますか?...

答えて

0

ここにFirebaseの開発者がいます。 Authの前にデータベースコンポーネントを使用すると、データベースコンポーネントが認証トークンの更新を見ていないことがわかりました。サインインが成功したとしても、データベースコンポーネントはまだ認証されません。

Firebase Unity SDKの4.2.0リリースで使用可能な修正を適用しました。 https://firebase.google.com/support/release-notes/unity#4.2.0

乾杯、 スチュワート

関連する問題