0

I am unable to access/edit a list variable inside a getvalueasync task, any code that tries to modify or read the list "ShopItems" returns nothing and prevents any further code from running in the same scope, no errors are being returned in the console. There are no issues with the "ItemsLoaded" int variable.

public static void IsItemPurchased(string item)
    {
        Debug.Log(ShopManager.ShopItems[0]); // This works
        FirebaseDatabase.DefaultInstance.GetReference("/Shop/" + item + "/").GetValueAsync().ContinueWith(task =>
        {
            if (task.IsFaulted || task.IsCanceled)
            {
                Debug.LogError("Database: Failed to check item status - " + task.Exception);
            }
            else if (task.IsCompleted)
            {
                bool isPurchased;
                if (task.Result.Value == null)
                    isPurchased = false;
                else
                    isPurchased = (bool)task.Result.Value;
                Debug.Log(ShopManager.ShopItems[0]); // Does not work
                Debug.Log(ShopManager.ItemsLoaded); // This works
                ShopManager.ShopItems.Where(i => i.gameObject.name == item).FirstOrDefault().Purchased = isPurchased; // Variable does not update
                ShopManager.ItemsLoaded++;
            }
        });
    }
sunjay
  • 1

1 Answers1

0

Some things to look at:

  • It's generally dangerous to change your game state based on the result of a GetValueAsync. See this SO answer for more details (it's an Android answer, but should apply to iOS too), but the general idea is that calling GetValueAsync will generally request data from the server and return whatever data is currently cached (so you miss out on the latest data if you're out of sync). It would be best to listen for the ValueChanged event and update shop items that way.
// important, cache this to cleanup later.
var shopReference = FirebaseDatabase.DefaultInstance.GetReference("/Shop/");

// your  have a Dictionary (or an Array if your items are more or less linear integers) from which you can get the value of all your items and update your shop accordingly. You could also listen per item in your shop.
shopReference.ValueChanged += HandleShopUpdated;

// important, do this in your OnDestroy. These are C# events with no knowledge of Unity's C# lifecycle
shopReference.ValueChanged -= HandleShopUpdated;
  • You're using ContinueWith instead of ContinueWithOnMainThread. Depending on your game, if any of these calls touches something in the UnityEngine namespace (say gameObject.name), it will likely raise an exception from being on the wrong thread. ContinueWithOnMainThread is a drop in replacement for ContinueWith, so consider using that.
  • General consideration since you're using ContinueWith rather than ContinueWithOnMainThread (ie: you can likely ignore this if you follow my previous recommendation). Since ItemsLoaded is accessed from a task, make sure you mark it as volatile. There is a small chance that you may miss an increment operation if multiple threads are working on the same piece of memory at once (fairly unlikely, but also difficult to catch).
Patrick Martin
  • 2,993
  • 1
  • 13
  • 11