带有 Unity 和 Firebase 数据库的字典数组 - 从键中获取值 [英] Array of dictionaries with Unity and Firebase database - Get values from key

查看:41
本文介绍了带有 Unity 和 Firebase 数据库的字典数组 - 从键中获取值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先 - 我对 Unity 还很陌生.

First of all - I am pretty new to Unity.

我正在尝试从我的 firebase 数据库中检索一些数据,将数据存储在一个数组/字典列表中,然后使用该数组/列表显示来自我的服务器的数据.

I am trying to retrieve some data from my firebase database, store the data in an array/list of dictionaries, and then use the array/list to show the data from my server.

所以...我尝试这样做的方式:

1:创建字典数组来保存我的数据:

1: Create array of dictionaries to hold my data:

[System.Serializable]
public class Global
{
   public static Dictionary<string, object>[] offers;
}

2:处理来自数据库的数据,并存入数组:

2: Handle the data from the database, and store it in the array:

void Handle_ChildAdded(object sender, ChildChangedEventArgs e)
    {
        if (e.DatabaseError != null)
        {
            Debug.LogError(e.DatabaseError.Message);
            return;
        }
        // Do something with the data in args.Snapshot
        if (e.Snapshot.Value != null)
        {
            var dict = e.Snapshot.Value as Dictionary<string, object>;

            if (dict != null)
            {
                Debug.Log(dict);
                Global.offers = new Dictionary<string, object>[Global.storesCount+1];
                Global.offers[Global.storesCount] = dict;
                Global.storesCount++;
                hasHaded = true;
            }
        }
    }

所以现在我在 Global.offers 数组中拥有了数据库中的所有快照.我应该得到的快照看起来像这样:

So now I have alle the snapshots from my database in my Global.offers array. The struckture of the snapshot i should get look something likes this:

是时候显示数组中的数据了

到目前为止一切正常 - 因为现在我需要显示我刚刚存储在 Global.offers 数组中的数据.我尝试用循环来做到这一点.我循环遍历数组并从我的数据库中搜索键并在游戏对象的预制件中实例化数据像这样:

Everything works fine until this point - Because now I need to show the data I just stored in my Global.offers array. I try to do that with a loop. I loop though the array and search for the keys from my database and Instantiate the data inside a prefab of a gameobject like this:

 for (int i = 0; i < Global.storesCount; i++)
        {
            Transform scrollViewObj = Instantiate(prefab, new Vector3(0, (downSize * i) - firstY, 0), Quaternion.identity);
            scrollViewObj.transform.SetParent(scrollContent.transform, false);
            scrollViewObj.transform.Find("Overskift").gameObject.GetComponent<Text>().text = Global.offers[i]["Store"] as string;
            scrollViewObj.transform.Find("Text (1)").gameObject.GetComponent<Text>().text = Global.offers[i]["Headline"] as string;
            scrollViewObj.transform.Find("Text (2)").gameObject.GetComponent<Text>().text = "Din pris: " + Global.offers[i]["Price"] as string + " kr.";
            scrollViewObj.transform.Find("Text (3)").gameObject.GetComponent<Text>().text = "Spar: " + Global.offers[i]["AndresPris"] as string + " kr.";
        }

这就是我遇到麻烦的地方.出于某种原因 Global.offers[i]["Store"] as string == null,当然意味着我无法实例化对象.我收到此错误:

This is where I get the trouble. For some reason Global.offers[i]["Store"] as string == null, witch of course means that I can't instantiate the object. I get this error:

NullReferenceException:未将对象引用设置为对象的实例LoadOffers.Start()(在 Assets/Scripts/LoadOffers.cs:36)

这太奇怪了,因为当我尝试调试时,我得到了一些相互矛盾的结果:

It is so weird, because when I try to debug I get some conflicting results:

数组的长度是19,所以不为空.

The length of the array is 19. So it is not empty.

当我尝试 Debug.Log 数组时,我得到:

When I try to Debug.Log the array out I get:

System.Collections.Generic.Dictionary`2[System.String,System.Object][]

System.Collections.Generic.Dictionary`2[System.String,System.Object][]

但是当我使用以下键搜索值时:

But when I search for values with keys like:

Debug.Log(Global.offers[0]["Store"]);

我得到的都是空的.我在值之后搜索错误吗?或者其他人能看到我做错了什么吗?

All I get is null. Am I searching wrong after the values? Or can anyone else see what I am doing wrong?

推荐答案

问题

您的主要问题是 Global.offers是一个数组,因此具有固定长度,不能那么简单地动态放大(您每次都必须复制数组!)

The Problem

Your main problem is that Global.offers is an array and therefore has a fixed length and can not be enlarged dynamically that simple (you would have to copy the array everytime!)

您尝试在 Handle_ChildAdded 中解决此问题,但在行中

You kind of tried to solve this in Handle_ChildAdded but in the line

Global.offers = new Dictionary<string, object>[Global.storesCount+1];

您实际做的是创建一个新的空(!)字典数组,长度为 Global.storeCount+1.您不会将当前值复制到新数组中.

what you actually do is creating a new empty(!) array of dictionaries with length Global.storeCount+1. You don't copy the current values to a new array.

所以在所有执行之后你得到的是一个只有 null 的数组.只有数组的最后一项才会有来自

so after all executions what you get is an array with only null. Only the last item of the array will have the content coming from

Global.offers[Global.storeCount] = dict;

所以实际上只会设置最后一个值.有点像

so only the last value will actually be set. It looks somewhat like

{null, null, null, null, ..., Dictionary<string, object> }

这就是长度是正确值的原因.您尝试访问的那一刻实际上已经抛出您的异常

that's why the length is a correct value. Your exception is actually already thrown the moment you try to access

Global.offers[0]

这是null.

我建议根本不要使用数组,而是使用 List 与数组相反,它可以动态增长

I would recommend not to use an array at all but instead a List which in contrary to the array can grow dynamically

[System.Serializable]
public class Global
{
   public static List<Dictionary<string, object>> offers = new List<Dictionary<string, object>>();
}

并且比之前通过添加您实际上应该在某处调用的所有字典开始填充列表

and than before starting to fill the list by adding all dictionaries you should actually somwhere call

Global.offers.Clear();

重置列表,否则它会随着数据库的每次加载而变得越来越大.此外,如果您绝对确定只在您可能不需要它时调用它,我总是建议这样做,以便获得一个干净的、通用的工作解决方案.

to reset the list otherwise it keeps growing bigger and bigger with every loading of the database. Also if you are absolutely sure you call this only once you might not need this I would always recommend to do it in order to have a clean, in general working solution.

然后在

void Handle_ChildAdded(object sender, ChildChangedEventArgs e)
{
    if (e.DatabaseError != null)
    {
        Debug.LogError(e.DatabaseError.Message);
        return;
    }
    // Do something with the data in args.Snapshot
    if (e.Snapshot.Value != null)
    {
        var dict = e.Snapshot.Value as Dictionary<string, object>;

        if (dict != null)
        {
            Debug.Log(dict);
            Global.offers.Add(dict);
            hasHaded = true;
        }
    }
}


稍后您可以像在数组中一样访问 List 中的元素

Debug.Log(Global.offers[0]["Store"]);


请注意,您的解决方案中也不需要变量 storeCount - 您可以简单地使用


Note that you also don't need the variable storeCount neither in your solution - you could have simply used

Global.offers.Length

也不在这个新的解决方案中 - 您可以简单地使用

nor in this new solution - you can simply use

Global.offers.Count

这篇关于带有 Unity 和 Firebase 数据库的字典数组 - 从键中获取值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆