Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database Firebase Unity-在GetValueAsync之后将所有子级放入数组/通用列表?_Database_Unity3d_Firebase_Firebase Realtime Database - Fatal编程技术网

Database Firebase Unity-在GetValueAsync之后将所有子级放入数组/通用列表?

Database Firebase Unity-在GetValueAsync之后将所有子级放入数组/通用列表?,database,unity3d,firebase,firebase-realtime-database,Database,Unity3d,Firebase,Firebase Realtime Database,如何从Unity3D中的Firebase数据库中以数组或通用列表的形式获取数据,而不提前知道子项的名称(键)? 我一直在尝试新的方法,我遇到了一个问题,即如何将所有的子项放到一个特定的位置,并将名称(键)和值放入数组或通用列表中,以便我可以在本地处理数据。请原谅我对Firebase如此陌生,可能使用了不好的技术来实现这一点,而这个插件如此新,我很难得到外界的帮助,因为Firebase Unity上没有太多的文档和教程 在这个特殊的例子中,我试图创建类似“即时消息”的功能,而不使用Firebase

如何从Unity3D中的Firebase数据库中以数组或通用列表的形式获取数据,而不提前知道子项的名称(键)?

我一直在尝试新的方法,我遇到了一个问题,即如何将所有的子项放到一个特定的位置,并将名称(键)和值放入数组或通用列表中,以便我可以在本地处理数据。请原谅我对Firebase如此陌生,可能使用了不好的技术来实现这一点,而这个插件如此新,我很难得到外界的帮助,因为Firebase Unity上没有太多的文档和教程

在这个特殊的例子中,我试图创建类似“即时消息”的功能,而不使用Firebase消息传递,而只是使用常规的Firebase数据库。使用Firebase消息传递可能会更容易,但主要是为了学习和定制,我只想通过Firebase数据库自己完成这项工作

我将数据插入数据库,如下所示:

public void SendMessage(string toUser, string msg)
{
    Debug.Log(String.Format("Attempting to send message from {0} to {1}", username, toUser));

    DatabaseReference reference = FirebaseDatabase.DefaultInstance.GetReference("Msgs");
    string date = Magnet.M.GetCurrentDate();

    // send data to the DB
    reference.Child(toUser).Child(username).Child(date).SetValueAsync(msg);
    // user receiving message / user sending message > VALUE = "hello dude|20170119111325"

    UpdateUsers();
}
public string[] GetConversation(string userA, string userB)
{
    // get a conversation between two users
    string[] convo = new string[0];

    FirebaseDatabase.DefaultInstance.GetReference("Msgs").GetValueAsync().ContinueWith(task =>
    {
        Debug.Log("Getting Conversation...");

        if (task.IsFaulted || task.IsCanceled)
        {
            Debug.LogError("ERROR: Task error in GetConversation(): " + task.Exception);
        }
        else if (task.IsCompleted)
        {
            DataSnapshot snapshot = task.Result;

            string[] messagesA = new string[0], messagesB = new string[0];

            if(snapshot.HasChild(userA))
            {
                // userA has a record of a conversation with other users
                if(snapshot.Child(userA).HasChild(userB)) // userB has sent messages to userA before
                {
                    Debug.Log("Found childA");
                    long count = snapshot.Child(userA).Child(userB).ChildrenCount;
                    messagesA = new string[count];
                    var kids = snapshot.Child(userA).Child(userB).Children;
                    Debug.Log(kids);
                    for (int i = 0; i < count; i++)
                    {
                        // this won't work, but is how I would like to access the data
                        messagesA[i] = kids[i].Value.ToString(); // AGAIN.... will not work...
                    }
                }
            }

            if(snapshot.HasChild(userB))
            {
                if(snapshot.Child(userB).HasChild(userA)) // userA sent a message to userB before
                {
                    Debug.Log("Found childB");
                    long count = snapshot.Child(userB).Child(userA).ChildrenCount;
                    messagesA = new string[count];
                    var kids = snapshot.Child(userB).Child(userA).Children;
                    Debug.Log(kids);
                    // messy incomplete testing code...
                }
            }

            // HERE I WOULD ASSIGN ALL THE MESSAGES BETWEEN A AND B AS 'convo'...
        }

        Debug.Log("Done Getting Conversation.");
    });


    return convo;
}
然后我试着像这样把它拿回来:

public void SendMessage(string toUser, string msg)
{
    Debug.Log(String.Format("Attempting to send message from {0} to {1}", username, toUser));

    DatabaseReference reference = FirebaseDatabase.DefaultInstance.GetReference("Msgs");
    string date = Magnet.M.GetCurrentDate();

    // send data to the DB
    reference.Child(toUser).Child(username).Child(date).SetValueAsync(msg);
    // user receiving message / user sending message > VALUE = "hello dude|20170119111325"

    UpdateUsers();
}
public string[] GetConversation(string userA, string userB)
{
    // get a conversation between two users
    string[] convo = new string[0];

    FirebaseDatabase.DefaultInstance.GetReference("Msgs").GetValueAsync().ContinueWith(task =>
    {
        Debug.Log("Getting Conversation...");

        if (task.IsFaulted || task.IsCanceled)
        {
            Debug.LogError("ERROR: Task error in GetConversation(): " + task.Exception);
        }
        else if (task.IsCompleted)
        {
            DataSnapshot snapshot = task.Result;

            string[] messagesA = new string[0], messagesB = new string[0];

            if(snapshot.HasChild(userA))
            {
                // userA has a record of a conversation with other users
                if(snapshot.Child(userA).HasChild(userB)) // userB has sent messages to userA before
                {
                    Debug.Log("Found childA");
                    long count = snapshot.Child(userA).Child(userB).ChildrenCount;
                    messagesA = new string[count];
                    var kids = snapshot.Child(userA).Child(userB).Children;
                    Debug.Log(kids);
                    for (int i = 0; i < count; i++)
                    {
                        // this won't work, but is how I would like to access the data
                        messagesA[i] = kids[i].Value.ToString(); // AGAIN.... will not work...
                    }
                }
            }

            if(snapshot.HasChild(userB))
            {
                if(snapshot.Child(userB).HasChild(userA)) // userA sent a message to userB before
                {
                    Debug.Log("Found childB");
                    long count = snapshot.Child(userB).Child(userA).ChildrenCount;
                    messagesA = new string[count];
                    var kids = snapshot.Child(userB).Child(userA).Children;
                    Debug.Log(kids);
                    // messy incomplete testing code...
                }
            }

            // HERE I WOULD ASSIGN ALL THE MESSAGES BETWEEN A AND B AS 'convo'...
        }

        Debug.Log("Done Getting Conversation.");
    });


    return convo;
}
public string[]GetConversation(string userA,string userB)
{
//获取两个用户之间的对话
string[]conva=新字符串[0];
FirebaseDatabase.DefaultInstance.GetReference(“Msgs”).GetValueAsync().ContinueWith(任务=>
{
Log(“获取对话…”);
if(task.IsFaulted | | task.IsCanceled)
{
LogError(“错误:GetConversation()中的任务错误:”+Task.Exception);
}
else if(任务已完成)
{
DataSnapshot快照=task.Result;
字符串[]messagesA=新字符串[0],messagesB=新字符串[0];
if(snapshot.HasChild(userA))
{
//userA有与其他用户的对话记录
if(snapshot.Child(userA.HasChild(userB))//userB以前曾向userA发送过消息
{
Debug.Log(“find childA”);
长计数=snapshot.Child(userA).Child(userB).ChildrenCount;
messagesA=新字符串[计数];
var kids=snapshot.Child(userA).Child(userB).Children;
Debug.Log(kids);
for(int i=0;i
但很明显,这是行不通的,因为DataSnapshot不允许我像使用索引的数组或通用列表一样访问它,而且当我不知道所有子项的名称(键)时,我也不知道如何处理数据,只想以任何顺序逐个地将它们取出。。。由于它们是按输入数据库的日期/时间命名的,我不会提前知道孩子们的名字(键),我不能只说“GetChild(“20170101010101”)”,因为这个数字是从任何客户端发送到数据库时生成的

仅供参考,以下是DB的外观:


这里是Firebase开发者


您是否尝试在顶级快照中使用值?它应该返回一个IDictionary,其中的值也可以是列表或嵌套字典。您必须使用一些动态检查来找出这些值。

找到了问题的答案。这是我的代码片段。希望这会有帮助

void InitializeFirebase() {


    FirebaseApp app = FirebaseApp.DefaultInstance;
    app.SetEditorDatabaseUrl ("https://slol.firebaseio.com/");

    FirebaseDatabase.DefaultInstance
        .GetReference ("Products").OrderByChild ("category").EqualTo("livingroom")
        .ValueChanged += (object sender2, ValueChangedEventArgs e2) => {
        if (e2.DatabaseError != null) {
            Debug.LogError (e2.DatabaseError.Message);
        }


        if (e2.Snapshot != null && e2.Snapshot.ChildrenCount > 0) {

            foreach (var childSnapshot in e2.Snapshot.Children) {
                var name = childSnapshot.Child ("name").Value.ToString (); 

                text.text = name.ToString();
                Debug.Log(name.ToString());
                //text.text = childSnapshot.ToString();

            }

        }

    };
}

谢谢你的回答,很高兴看到其他人是如何解决类似问题的,尽管我使用了@Benjamin的不同解决方案,我在上面接受了。我试图编辑他的答案,以显示我的代码,这对我来说是有效的,但它不被接受作为编辑,对不起!不过,再次感谢您的投入!