Search Unity

Firebase Database problem

Discussion in 'Multiplayer' started by frankoprus, Sep 25, 2020.

  1. frankoprus

    frankoprus

    Joined:
    Oct 22, 2019
    Posts:
    6
    Hello,
    So I have a game with the mainMenu scene and Play scene. After I log in with LoginButton() the Text: usernameText is not updating, when I'm changing to Play scene and come back to mainMenu it is updating. displayScores is updating only after I log in again with LoginButton(). So to see the refreshed result table I have to click the LoginButton() again even though I am logged in. And after restarting the application in the editor, I see in the logs that I am logged in correctly, but the usernameText does not match the username again.
    Everything is updating correctly on the server-side.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Firebase;
    5. using Firebase.Auth;
    6. using TMPro;
    7. using System;
    8. using Firebase.Database;
    9. using Firebase.Unity.Editor;
    10. using JetBrains.Annotations;
    11. using UnityEngine.UI;
    12.  
    13.  
    14.  
    15. public class AuthManager : MonoBehaviour
    16. {
    17.     //Firebase variables
    18.     [Header("Firebase")]
    19.     public DependencyStatus dependencyStatus;
    20.     public FirebaseAuth auth;
    21.     public FirebaseUser User;
    22.  
    23.     //Login variables
    24.     [Header("Login")]
    25.     public TMP_InputField emailLoginField;
    26.     public TMP_InputField passwordLoginField;
    27.     public TMP_Text warningLoginText;
    28.     public TMP_Text confirmLoginText;
    29.  
    30.     //Register variables
    31.     [Header("Register")]
    32.     public TMP_InputField usernameRegisterField;
    33.     public TMP_InputField emailRegisterField;
    34.     public TMP_InputField passwordRegisterField;
    35.     public TMP_InputField passwordRegisterVerifyField;
    36.     public TMP_Text warningRegisterText;
    37.  
    38.     public string userName;
    39.     public Text usernameText;
    40.  
    41.     ArrayList leaderBoard;
    42.     public Text displayScores;
    43.     private bool addScorePressed;
    44.     private const int MaxScores = 5;
    45.     private int score = 100;
    46.  
    47.  
    48.     private string DATA_URL = "https://test-game.firebaseio.com/";
    49.  
    50.     private DatabaseReference databaseReference;
    51.     //private DependencyStatus dependencyStatus;
    52.  
    53.     void Awake()
    54.     {
    55.         //Check that all of the necessary dependencies for Firebase are present on the system
    56.         FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task =>
    57.         {
    58.             dependencyStatus = task.Result;
    59.             if (dependencyStatus == DependencyStatus.Available)
    60.             {
    61.                 //If they are avalible Initialize Firebase
    62.                 InitializeFirebase();
    63.             }
    64.             else
    65.             {
    66.                 Debug.LogError("Could not resolve all Firebase dependencies: " + dependencyStatus);
    67.             }
    68.         });
    69.     }
    70.  
    71.     private void Start()
    72.     {
    73.         addScorePressed = true;
    74.         leaderBoard = new ArrayList();
    75.         leaderBoard.Add("Top " + MaxScores.ToString() + " Scores");
    76.  
    77.         Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task =>
    78.         {
    79.             dependencyStatus = task.Result;
    80.             if (dependencyStatus == DependencyStatus.Available)
    81.             {
    82.                 InitializeFirebase();
    83.             }
    84.             else
    85.             {
    86.                 Debug.LogError("Could not resolve all Firebase dependencies: " + dependencyStatus);
    87.             }
    88.         });
    89.     }
    90.  
    91.  
    92.     //protected void InitializeFirebaseData()
    93.     //{
    94.     //    FirebaseApp.DefaultInstance.SetEditorDatabaseUrl(DATA_URL);
    95.     //    databaseReference = FirebaseDatabase.DefaultInstance.RootReference;
    96.     //    StartListener();      
    97.     //}
    98.  
    99.     //private void InitializeFirebase()
    100.     //{
    101.     //    //Set the authentication instance object
    102.     //    auth = FirebaseAuth.DefaultInstance;
    103.     //    //Debug.Log("Setting up Firebase Auth");
    104.     //    UpdateInitialize();
    105.     //}
    106.  
    107.     private void InitializeFirebase()
    108.     {
    109.         auth = FirebaseAuth.DefaultInstance;
    110.  
    111.         FirebaseApp.DefaultInstance.SetEditorDatabaseUrl(DATA_URL);
    112.         databaseReference = FirebaseDatabase.DefaultInstance.RootReference;
    113.         StartListener();
    114.  
    115.         UpdateInitialize();
    116.     }
    117.  
    118.     public void UpdateInitialize()
    119.     {
    120.         if (auth.CurrentUser != null)
    121.         {
    122.             var user = auth.CurrentUser;
    123.             Debug.LogFormat("User signed in succesfully: {0} ({1})", user.DisplayName, user.Email);
    124.             userName = user.DisplayName;
    125.             usernameText.text = user.DisplayName;
    126.         }
    127.     }
    128.  
    129.     public void writeNewUser(string email, string name, string pass, int score)
    130.     {
    131.         Player user = new Player( emailRegisterField.text, usernameRegisterField.text, passwordRegisterField.text, PlayerPrefs.GetInt("HighScore"));
    132.         string json = JsonUtility.ToJson(user);
    133.         databaseReference.Child("users").Push().SetRawJsonValueAsync(json);
    134.     }
    135.  
    136.  
    137.     public void WriteNewScore(string userId, int score)
    138.     {
    139.         // Create new entry at /user-scores/$userid/$scoreid and at
    140.         // /leaderboard/$scoreid simultaneously
    141.         string key = databaseReference.Child(userId)/*.Push()*/.Key;
    142.         LeaderboardEntry entry = new LeaderboardEntry(userId, score);
    143.         Dictionary<string, object> entryValues = entry.ToDictionary();
    144.  
    145.         Dictionary<string, object> childUpdates = new Dictionary<string, object>();
    146.         //childUpdates["/scores/" + key] = entryValues;
    147.         childUpdates["/Highscore/" /*+ userId*/ + "/" + key] = entryValues;
    148.  
    149.         databaseReference.UpdateChildrenAsync(childUpdates);
    150.     }
    151.  
    152.     protected void StartListener()
    153.     {
    154.         FirebaseDatabase.DefaultInstance
    155.           .GetReference("Highscore").OrderByChild("score")
    156.           .ValueChanged += (object sender2, ValueChangedEventArgs e2) => {
    157.               if (e2.DatabaseError != null)
    158.               {
    159.                   Debug.LogError(e2.DatabaseError.Message);
    160.                   return;
    161.               }
    162.               //Debug.Log("Received values for Leaders.");
    163.               string title = leaderBoard[0].ToString();
    164.               leaderBoard.Clear();
    165.               leaderBoard.Add(title);
    166.               if (e2.Snapshot != null && e2.Snapshot.ChildrenCount > 0)
    167.               {
    168.                   foreach (var childSnapshot in e2.Snapshot.Children)
    169.                   {
    170.                       if (childSnapshot.Child("score") == null
    171.                     || childSnapshot.Child("score").Value == null)
    172.                       {
    173.                           Debug.LogError("Bad data in sample.  Did you forget to call SetEditorDatabaseUrl with your project id?");
    174.                           break;
    175.                       }
    176.                       else
    177.                       {
    178.                         //  Debug.Log("Leaders entry : " +
    179.                         //childSnapshot.Child("uid").Value.ToString() + " - " +
    180.                         //childSnapshot.Child("score").Value.ToString());
    181.                           leaderBoard.Insert(1, childSnapshot.Child("score").Value.ToString()
    182.                         + " . . . . . . " + childSnapshot.Child("uid").Value.ToString());
    183.  
    184.                           displayScores.text = "";
    185.                           foreach (string item in leaderBoard)
    186.                           {
    187.                               displayScores.text += "\n" + item;
    188.                           }
    189.                       }
    190.                   }
    191.               }
    192.           };
    193.     }
    194.     // DataBase^
    195.  
    196.  
    197.     //Function for the login button
    198.     public void LoginButton()
    199.     {
    200.         //Call the login coroutine passing the email and password
    201.         StartCoroutine(Login(emailLoginField.text, passwordLoginField.text));
    202.     }
    203.  
    204.     public void AutoLoginButton()
    205.     {
    206.         StartCoroutine(AutoLogin(PlayerPrefs.GetString("userEmail"), PlayerPrefs.GetString("userPassword")));
    207.     }
    208.     //Function for the register button
    209.     public void RegisterButton()
    210.     {
    211.         //Call the register coroutine passing the email, password, and username
    212.         StartCoroutine(Register(emailRegisterField.text, passwordRegisterField.text, usernameRegisterField.text));
    213.     }
    214.  
    215.     public void SingOutButton()
    216.     {
    217.         auth.SignOut();
    218.     }
    219.  
    220.     private IEnumerator Login(string _email, string _password)
    221.     {
    222.         //Call the Firebase auth signin function passing the email and password
    223.         var LoginTask = auth.SignInWithEmailAndPasswordAsync(_email, _password);
    224.         //Wait until the task completes
    225.         yield return new WaitUntil(predicate: () => LoginTask.IsCompleted);
    226.  
    227.         if (LoginTask.Exception != null)
    228.         {
    229.             //If there are errors handle them
    230.             Debug.LogWarning(message: $"Failed to register task with {LoginTask.Exception}");
    231.             FirebaseException firebaseEx = LoginTask.Exception.GetBaseException() as FirebaseException;
    232.             AuthError errorCode = (AuthError)firebaseEx.ErrorCode;
    233.  
    234.             string message = "Login Failed!";
    235.             switch (errorCode)
    236.             {
    237.                 case AuthError.MissingEmail:
    238.                     message = "Missing Email";
    239.                     break;
    240.                 case AuthError.MissingPassword:
    241.                     message = "Missing Password";
    242.                     break;
    243.                 case AuthError.WrongPassword:
    244.                     message = "Wrong Password";
    245.                     break;
    246.                 case AuthError.InvalidEmail:
    247.                     message = "Invalid Email";
    248.                     break;
    249.                 case AuthError.UserNotFound:
    250.                     message = "Account does not exist";
    251.                     break;
    252.             }
    253.             warningLoginText.text = message;
    254.         }
    255.         else
    256.         {
    257.             //User is now logged in
    258.             //Now get the result          
    259.             User = LoginTask.Result;
    260.             Debug.LogFormat("User signed in successfully: {0} ({1})", User.DisplayName, User.Email);
    261.             warningLoginText.text = "";
    262.             confirmLoginText.text = "Logged In";
    263.            
    264.             WriteNewScore(User.DisplayName, PlayerPrefs.GetInt("HighScore"));
    265.             string name = User.DisplayName;          
    266.  
    267.             // Database
    268.             DatabaseReference reference = FirebaseDatabase.DefaultInstance.GetReference("Highscore");
    269.  
    270.             reference.RunTransaction(AddScoreTransaction)
    271.                  .ContinueWith(task => {
    272.                  if (task.Exception != null)
    273.                  {
    274.                      Debug.Log(task.Exception.ToString());
    275.                  }
    276.                  else if (task.IsCompleted)
    277.                  {
    278.                      Debug.Log("Transaction complete.");
    279.                  }
    280.              });
    281.             //update UI
    282.             addScorePressed = true;
    283.             usernameText.text = name.ToString();
    284.         }
    285.     }
    286.  
    287.     private IEnumerator Register(string _email, string _password, string _username)
    288.     {
    289.         if (_username == "")
    290.         {
    291.             //If the username field is blank show a warning
    292.             warningRegisterText.text = "Missing Username";
    293.         }
    294.         else if (passwordRegisterField.text != passwordRegisterVerifyField.text)
    295.         {
    296.             //If the password does not match show a warning
    297.             warningRegisterText.text = "Password Does Not Match!";
    298.         }
    299.         else
    300.         {
    301.             //Call the Firebase auth signin function passing the email and password
    302.             var RegisterTask = auth.CreateUserWithEmailAndPasswordAsync(_email, _password);
    303.             //Wait until the task completes
    304.             yield return new WaitUntil(predicate: () => RegisterTask.IsCompleted);
    305.  
    306.             if (RegisterTask.Exception != null)
    307.             {
    308.                 //If there are errors handle them
    309.                 Debug.LogWarning(message: $"Failed to register task with {RegisterTask.Exception}");
    310.                 FirebaseException firebaseEx = RegisterTask.Exception.GetBaseException() as FirebaseException;
    311.                 AuthError errorCode = (AuthError)firebaseEx.ErrorCode;
    312.  
    313.                 string message = "Register Failed!";
    314.                 switch (errorCode)
    315.                 {
    316.                     case AuthError.MissingEmail:
    317.                         message = "Missing Email";
    318.                         break;
    319.                     case AuthError.MissingPassword:
    320.                         message = "Missing Password";
    321.                         break;
    322.                     case AuthError.WeakPassword:
    323.                         message = "Weak Password";
    324.                         break;
    325.                     case AuthError.EmailAlreadyInUse:
    326.                         message = "Email Already In Use";
    327.                         break;
    328.                 }
    329.                 warningRegisterText.text = message;
    330.             }
    331.             else
    332.             {
    333.                 //User has now been created
    334.                 //Now get the result
    335.  
    336.                 writeNewUser(emailRegisterField.text, usernameRegisterField.text, passwordRegisterField.text, PlayerPrefs.GetInt("HighScore"));
    337.                
    338.  
    339.                 User = RegisterTask.Result;
    340.  
    341.                 if (User != null)
    342.                 {
    343.                     //Create a user profile and set the username
    344.                     UserProfile profile = new UserProfile { DisplayName = _username };
    345.  
    346.                     //Call the Firebase auth update user profile function passing the profile with the username
    347.                     var ProfileTask = User.UpdateUserProfileAsync(profile);
    348.                     //Wait until the task completes
    349.                     yield return new WaitUntil(predicate: () => ProfileTask.IsCompleted);
    350.  
    351.                     if (ProfileTask.Exception != null)
    352.                     {
    353.                         //If there are errors handle them
    354.                         Debug.LogWarning(message: $"Failed to register task with {ProfileTask.Exception}");
    355.                         FirebaseException firebaseEx = ProfileTask.Exception.GetBaseException() as FirebaseException;
    356.                         AuthError errorCode = (AuthError)firebaseEx.ErrorCode;
    357.                         warningRegisterText.text = "Username Set Failed!";
    358.                     }
    359.                     else
    360.                     {
    361.                         //Username is now set
    362.                         //Now return to login screen
    363.  
    364.                         PlayerPrefs.SetString("userEmail", emailRegisterField.text);
    365.                         PlayerPrefs.SetString("userPassword", emailRegisterField.text);                                          
    366.                         warningRegisterText.text = "";
    367.                         StartCoroutine(AutoLogin(PlayerPrefs.GetString("userEmail"), PlayerPrefs.GetString("userPassword")));
    368.                         LoginUIManager.instance.BackToMenu();
    369.                     }
    370.                 }
    371.             }
    372.         }
    373.     }
    374.  
    375.     private IEnumerator AutoLogin(string _email, string _password)
    376.     {
    377.         //Call the Firebase auth signin function passing the email and password
    378.         var LoginTask = auth.SignInWithEmailAndPasswordAsync(PlayerPrefs.GetString("userEmail"), PlayerPrefs.GetString("userPassword"));
    379.         //Wait until the task completes
    380.         yield return new WaitUntil(predicate: () => LoginTask.IsCompleted);
    381.  
    382.         //if (LoginTask.Exception != null)
    383.         //{
    384.         //    //If there are errors handle them
    385.         //    Debug.LogWarning(message: $"Failed to register task with {LoginTask.Exception}");
    386.         //    FirebaseException firebaseEx = LoginTask.Exception.GetBaseException() as FirebaseException;
    387.         //    AuthError errorCode = (AuthError)firebaseEx.ErrorCode;
    388.  
    389.         //    string message = "Login Failed!";
    390.         //    switch (errorCode)
    391.         //    {
    392.         //        case AuthError.MissingEmail:
    393.         //            message = "Missing Email";
    394.         //            break;
    395.         //        case AuthError.MissingPassword:
    396.         //            message = "Missing Password";
    397.         //            break;
    398.         //        case AuthError.WrongPassword:
    399.         //            message = "Wrong Password";
    400.         //            break;
    401.         //        case AuthError.InvalidEmail:
    402.         //            message = "Invalid Email";
    403.         //            break;
    404.         //        case AuthError.UserNotFound:
    405.         //            message = "Account does not exist";
    406.         //            break;
    407.         //    }
    408.         //    warningLoginText.text = message;
    409.         //}
    410.         //else
    411.         //{
    412.             //User is now logged in
    413.             //Now get the result          
    414.             User = LoginTask.Result;
    415.             Debug.LogFormat("User signed in successfully: {0} ({1})", User.DisplayName, User.Email);
    416.             warningLoginText.text = "";
    417.             confirmLoginText.text = "Logged In";
    418.  
    419.             WriteNewScore(User.DisplayName, PlayerPrefs.GetInt("HighScore"));
    420.             string name = User.DisplayName;
    421.  
    422.             // Database
    423.             DatabaseReference reference = FirebaseDatabase.DefaultInstance.GetReference("Highscore");
    424.  
    425.             reference.RunTransaction(AddScoreTransaction)
    426.                  .ContinueWith(task => {
    427.                      if (task.Exception != null)
    428.                      {
    429.                          Debug.Log(task.Exception.ToString());
    430.                      }
    431.                      else if (task.IsCompleted)
    432.                      {
    433.                          Debug.Log("Transaction complete.");
    434.                      }
    435.                  });
    436.             //update UI
    437.             addScorePressed = true;
    438.             usernameText.text = name.ToString();
    439.         //}
    440.     }
    441.  
    442.     // Database:
    443.  
    444.     TransactionResult AddScoreTransaction(MutableData mutableData)
    445.     {
    446.         List<object> leaders = mutableData.Value as List<object>;
    447.  
    448.         if (leaders == null)
    449.         {
    450.             leaders = new List<object>();
    451.         }
    452.         else if (mutableData.ChildrenCount >= MaxScores)
    453.         {
    454.             // If the current list of scores is greater or equal to our maximum allowed number,
    455.             // we see if the new score should be added and remove the lowest existing score.
    456.             long minScore = long.MaxValue;
    457.             object minVal = null;
    458.             foreach (var child in leaders)
    459.             {
    460.                 if (!(child is Dictionary<string, object>))
    461.                     continue;
    462.                 long childScore = (long)((Dictionary<string, object>)child)["score"];
    463.                 if (childScore < minScore)
    464.                 {
    465.                     minScore = childScore;
    466.                     minVal = child;
    467.                 }
    468.             }
    469.             // If the new score is lower than the current minimum, we abort.
    470.             if (minScore > score)
    471.             {
    472.                 return TransactionResult.Abort();
    473.             }
    474.             // Otherwise, we remove the current lowest to be replaced with the new score.
    475.             leaders.Remove(minVal);
    476.         }
    477.  
    478.         // Now we add the new score as a new entry that contains the email address and score.
    479.         Dictionary<string, object> newScoreMap = new Dictionary<string, object>();
    480.         newScoreMap["score"] = score;
    481.         newScoreMap["uid"] = name;
    482.         leaders.Add(newScoreMap);
    483.  
    484.         // You must set the Value to indicate data at that location has changed.
    485.         mutableData.Value = leaders;
    486.         //return and log success
    487.         return TransactionResult.Success(mutableData);
    488.     }
    489.  
    490. }
     
  2. Sound-Master

    Sound-Master

    Joined:
    Aug 1, 2017
    Posts:
    48
    I don't know if this would help, as I am not sure I understand your code 100%.

    I was having a similar issue. I was not able to update text of activate gameobjects when retrieving items from the database. the reason in my case is that I was using continueWith, meaning stuff was happening on a different thread but somehow Unity was not catching it. The solution was to use continueWithOnMainThread instead.

    See the issue I posted on the firebase github here. Also this blog post might help.
     
    OleksandrMartysh and Vroomy23 like this.
  3. frankoprus

    frankoprus

    Joined:
    Oct 22, 2019
    Posts:
    6
    Im not using continueWith and continueWithOnMainThread.

    I found that Debug.Log stops there:

    Code (CSharp):
    1.     public void UpdatePlayer()
    2.     {
    3.         if (auth.CurrentUser != null)
    4.         {
    5.             var user = auth.CurrentUser;
    6.             Debug.LogFormat("User signed in succesfully: {0} ({1})", user.DisplayName, user.Email);
    7.             // Deug.Log stops here
    8.             userName = user.DisplayName;
    9.             usernameText.text = user.DisplayName.ToString();
    10.             Debug.Log("FirebaseInitialized");
    11.         }
    12.  
    13.     }
     
  4. tcshaw91

    tcshaw91

    Joined:
    Jul 26, 2018
    Posts:
    9
    Check Lines 77, 271, and 426 of what you posted. Pretty sure you're using continueWith :p
     
    Vroomy23 likes this.
  5. frankoprus

    frankoprus

    Joined:
    Oct 22, 2019
    Posts:
    6
    You're right.
    I tried to use continueWithOnMainThread but I receive strange errors, I have no idea how to handle them... 1.png 2.png
     
  6. Sound-Master

    Sound-Master

    Joined:
    Aug 1, 2017
    Posts:
    48
    If you click on 'show potential fixes' it will probably suggest adding
    Code (CSharp):
    1. using Firebase.Extensions;
    . That's what did the trick for me. I think the firebase extensions used to be a separate package, but I believe they have now been integrated into something else. Anyway, as soon as I added that line the error went away.

    I hope this helps.
     
    Vroomy23 and frankoprus like this.
  7. bhupiister

    bhupiister

    Joined:
    Dec 13, 2019
    Posts:
    42
    @frankoprus : how are you able to use "SetEditorDatabaseUrl". I downloaded a new version of Firebase SDK and it shows that it's deprecated/obsolete. I have no clue how to run it in the editor anymore. It's pain in the ass to test it on mobile again and again.
     
  8. snirego75

    snirego75

    Joined:
    Aug 13, 2017
    Posts:
    1
    Did you find the solution for that? I am trying it for the past two days and not found something yet
     
  9. bhupiister

    bhupiister

    Joined:
    Dec 13, 2019
    Posts:
    42
    Try this and let me know if it works... @snirego75
    Code (CSharp):
    1.      
    2. FirebaseApp app;
    3.     void Start()
    4.     {
    5.       app = FirebaseApp.DefaultInstance;
    6.       Uri uri = new Uri("https://appname-0000.firebaseio.com/");//Your firebase url
    7.       app.Options.DatabaseUrl = uri;
    8.     }
    9.  
     
    Last edited: Mar 19, 2021
  10. atulvi

    atulvi

    Joined:
    Oct 28, 2020
    Posts:
    35
    SetEditorDatabaseUrl Deprecated ?

    FirebaseApp.DefaultInstance.SetEditorDatabaseUrl("https://yourapp-a6192.firebaseio.com/"); // SetEditorDatabaseUrl is deprecated in latest version of firebase please comment the line of code in script.

    Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task => {
    var dependencyStatus = task.Result;
    if (dependencyStatus == Firebase.DependencyStatus.Available) {
    // Create and hold a reference to your FirebaseApp,
    // where app is a Firebase.FirebaseApp property of your application class.
    app = Firebase.FirebaseApp.DefaultInstance;

    // Set a flag here to indicate whether Firebase is ready to use by your app.
    } else {
    UnityEngine.Debug.LogError(System.String.Format(
    "Could not resolve all Firebase dependencies: {0}", dependencyStatus));
    // Firebase Unity SDK is not safe to use here.
    }
    });

    Note : Open the link https://firebase.google.com/docs/unity/setup?authuser=0 Read Step 5.