首页 > 解决方案 > 将数据保存并加载到 Firebase 无法统一工作

问题描述

也许我的代码会在这里乱七八糟,因为我是 firebase 的新手,而且像我这样的新手缺少文档,所以我想从 firebase 保存和加载数据,第一个场景有 2 个场景main menu,第二个场景有main game,所以当首次登录或自动登录,用户current user将从实时数据库加载数据(I'm using firebase)返回主菜单时也适用于用户。

在第二个场景本身中,用户在第一次开始时加载当前用户高分数据,然后当游戏结束时,如果score > lasthighscore将最新的高分保存/更新到实时数据库。

这里的预览是我自动登录然后玩游戏直到游戏结束:

它应该更新,但返回主菜单时不会更新,我已经尝试使用播放器首选项,因为我在退出时删除了所有数据,因此高分始终为 0,如果使用其他帐户登录,则高分不属于其他帐户。这是我在主菜单上的firebase脚本:

   private void Start()
    {
        Time.timeScale = 1;
        mainPanel.SetActive(true);
        InitializeFirebase();
    }

    void InitializeFirebase()
    {
        auth = FirebaseAuth.DefaultInstance;
        DBreference = FirebaseDatabase.DefaultInstance.RootReference;
        auth.StateChanged += AuthStateChanged;
        AuthStateChanged(this, null);
    }

    void AuthStateChanged(object sender, System.EventArgs eventArgs)
    {
        //This checks if the user (your local user) is the same as the one from the auth
        if (auth.CurrentUser != User)
        {
            //this seems the same, but user could have been null before
            bool signedIn = User != auth.CurrentUser && auth.CurrentUser != null;
            if (!signedIn && User != null)
            {
                Debug.Log("Signed out " + User.UserId);
                loginPanel.SetActive(true);
            }
            //this is important step, this user is the one you should be working with
            User = auth.CurrentUser;
            if (signedIn)
            {
                Debug.Log("Signed in " + User.UserId);
                userNameShowText.text = User.DisplayName;
                StartCoroutine(LoadUserData());
                loginPanel.SetActive(false);

                //            //highScoreMainMenu.text = PlayerPrefs.GetInt("highscore").ToString("0000000");

            }
            else
            {
                loginPanel.SetActive(true);
            }
        }
    }
    
     public IEnumerator Login(string _email, string _password)
    {
        //Call the Firebase auth signin function passing the email and password
        var LoginTask = auth.SignInWithEmailAndPasswordAsync(_email, _password);
        //Wait until the task completes
        yield return new WaitUntil(predicate: () => LoginTask.IsCompleted);

        if (LoginTask.Exception != null)
        {
            //If there are errors handle them
            Debug.LogWarning(message: $"Failed to register task with {LoginTask.Exception}");
            FirebaseException firebaseEx = LoginTask.Exception.GetBaseException() as FirebaseException;
            AuthError errorCode = (AuthError)firebaseEx.ErrorCode;

            string message = "Login Failed!";
            switch (errorCode)
            {
                case AuthError.MissingEmail:
                    message = "Missing Email";
                    break;
                case AuthError.MissingPassword:
                    message = "Missing Password";
                    break;
                case AuthError.WrongPassword:
                    message = "Wrong Password";
                    break;
                case AuthError.InvalidEmail:
                    message = "Invalid Email";
                    break;
                case AuthError.UserNotFound:
                    message = "Account does not exist";
                    break;
            }
            warningLoginText.text = message;
        }
        else
        {
            //User is now logged in
            //Now get the result
            User = LoginTask.Result;
            Debug.LogFormat("User signed in successfully: {0} ({1})", User.DisplayName, User.Email);
            warningLoginText.text = "";
            confirmLoginText.text = "Logged In";

            StartCoroutine(LoadUserData());

            yield return new WaitForSeconds(2);

            userNameShowText.text = User.DisplayName;
            UserDataScreen(); // Change to user data UI
            confirmLoginText.text = "";
            ClearLoginFeilds();
            ClearRegisterFeilds();
        }
    }

     public IEnumerator UpdateHighScore(int _highScore)
    {
        var DBTask = DBreference.Child("users").Child(auth.CurrentUser.UserId).Child("highscore").SetValueAsync(_highScore);

        yield return new WaitUntil(predicate: () => DBTask.IsCompleted);

        if (DBTask.Exception != null)
        {
            Debug.LogWarning(message: $"Failed to register task with {DBTask.Exception}");
        }
        else
        {
           //giscrore now updated
        }
    }

这适用于游戏场景,也与主菜单上的更新 higscore 功能相同。

void Start()
    {
        InitializeFirebase();

        YetGameOver();
        //GetScore
        score = 0;
        scoreText.text = score.ToString("00000");
        //highScoreText.text = "HI :" + PlayerPrefs.GetInt("highscore", 0).ToString("00000");
        maxTime = .1f;
    }

   void InitializeFirebase()
    {
        auth = FirebaseAuth.DefaultInstance;
        DBreference = FirebaseDatabase.DefaultInstance.RootReference;
        auth.StateChanged += AuthStateChanged;
        AuthStateChanged(this, null);
    }

    void AuthStateChanged(object sender, System.EventArgs eventArgs)
    {
        //This checks if the user (your local user) is the same as the one from the auth
        if (auth.CurrentUser != User)
        {
            //this seems the same, but user could have been null before
            bool signedIn = User != auth.CurrentUser && auth.CurrentUser != null;
            if (!signedIn && User != null)
            {
                Debug.Log("Signed out " + User.UserId);
            }
            //this is important step, this user is the one you should be working with
            User = auth.CurrentUser;
            if (signedIn)
            {
                Debug.Log("Signed in " + User.UserId);
                StartCoroutine(LoadUserData());
                //highScoreMainMenu.text = PlayerPrefs.GetInt("highscore").ToString("0000000");

            }
        }
    }

  public void GameOver()
    {
        SaveData();
        StartCoroutine(WaitToDeath());
    }

public void SaveData()
    {
        Debug.Log("Saved");
        StartCoroutine(UpdateHighScore(PlayerPrefs.GetInt("highscore", 0)));
    }

 public IEnumerator WaitToDeath()
    {

        _CamShake.instance.shouldShake = true;

        DeathSound();

        gameOverPanel.SetActive(true);

        endHighScoreText.text = "HI :" + PlayerPrefs.GetInt("highscore").ToString("0000000");
        scoreText.gameObject.SetActive(false);
        highScoreText.gameObject.SetActive(false);

        yield return new WaitForSeconds(.1f);

        //_AdmobAds.instance.ShowInterstitialAd();
        isStarted = false;
        isGameOver = true;
        Time.timeScale = 0;
    }
//same function like main menu
public IEnumerator UpdateHighScore(int _highScore)
    {
        var DBTask = DBreference.Child("users").Child(auth.CurrentUser.UserId).Child("highscore").SetValueAsync(_highScore);

        yield return new WaitUntil(predicate: () => DBTask.IsCompleted);

        if (DBTask.Exception != null)
        {
            Debug.LogWarning(message: $"Failed to register task with {DBTask.Exception}");
        }
        else
        {
            //highscore are now updated
            
        }
    }

public IEnumerator LoadUserData()
    {
        //Get the currently logged in user data
        var DBTask = DBreference.Child("users").Child(User.UserId).GetValueAsync();

        yield return new WaitUntil(predicate: () => DBTask.IsCompleted);

        if (DBTask.Exception != null)
        {
            Debug.LogWarning(message: $"Failed to register task with {DBTask.Exception}");
        }
        else if (DBTask.Result.Value == null)
        {
            //No data exists yet
            highScoreText.text = "0";
            endHighScoreText.text = "0";
        }
        else
        {
            //Data has been retrieved
            DataSnapshot snapshot = DBTask.Result;
            highScoreText.text = endHighScoreText.text = snapshot.Child("highscore").Value.ToString();
        }
    }

标签: firebaseunity3dfirebase-realtime-database

解决方案


推荐阅读