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を取得するたびに。しかし、データベースの直後にはデータベース自体にアクセスすることはできませんが、ユーザーは確実に正しく認証され、アクセス権が必要です。私は困惑し、それがどのように可能か理解していない。誰でもここで何が起こっているのか分かりますか?...