C# 如何从Untiy获得Firebase控制台的最新ID

C# 如何从Untiy获得Firebase控制台的最新ID,c#,firebase,unity3d,firebase-realtime-database,C#,Firebase,Unity3d,Firebase Realtime Database,我有一个与Firebase合作的统一项目,用于谷歌认证。我将用户信息存储在实时数据库中。它们存储为: UnityProject 1-> Name: "Something" Email: "Something" 2-> Name: "some other thing" Email: "Something else" 现在,这1,2将由我给出,用作主键。我首先给出第一个用户ID 1和第二个用户ID 2,依此类推 但

我有一个与Firebase合作的统一项目,用于谷歌认证。我将用户信息存储在实时数据库中。它们存储为:

UnityProject
    1->
       Name: "Something"
       Email: "Something"
    2->
       Name: "some other thing"
       Email: "Something else"
现在,这1,2将由我给出,用作主键。我首先给出第一个用户ID 1和第二个用户ID 2,依此类推

但我需要从消防基地取回上次储存的身份证。比如说,

idToInsert = GetLastUsedID() + 1;
我使用过这个代码,但它不起作用。屏幕冻结,直到我强制关闭

 public int GetLastUsedID()
    {
        int currentID = 1;
        bool continueSearch = true;

        while (continueSearch)
        {
            FirebaseREST.DatabaseReference reference = FirebaseREST.FirebaseDatabase.Instance.GetReference(""+currentID);
            string value = "";
            currentID++;
            reference.GetValueAsync(10, (res) =>
            {
                if (res.success)
                {
                    value = res.data.GetRawJsonValue();
                    Debug.Log("Success fetched data : " + value);
                    if(value == "")
                    {
                        continueSearch = false;
                        Debug.Log(currentID);
                    }
                }
                else
                {
                    Debug.Log("Fetch data failed : " + res.message);
                    continueSearch = false;
                }
            });

        }
        return currentID;
}
基本上,我只是尝试从1迭代,直到得到空字符串。空字符串表示该ID下不存在任何数据。

我不熟悉FirebaseREST,我建议使用。如果可以,它不仅仅是调用REST端点,但我想我可以看到您的问题

GetValueAsync可能在后台异步运行。所以块内的逻辑res=>部分在while循环中基本上无限次地触发。然后,根据实现方式的不同,continueSearch永远不会变为false,因为它没有被标记,或者回调逻辑永远不会有机会运行,比如说如果FirebaseREST尝试调度到主线程,该线程被锁定在无限while循环中

如果GetValueAsync返回任务,您可以使用我在中介绍的一些技巧。我的建议是尝试使用async/await,这样您的逻辑看起来更像:

async public int GetLastUsedID()
{
    volatile int currentID = 1;
    volatile bool continueSearch = true;

    while (continueSearch)
    {
        FirebaseREST.DatabaseReference reference = FirebaseREST.FirebaseDatabase.Instance.GetReference(""+currentID);
        string value = "";
        currentID++;
        await reference.GetValueAsync(10, (res) =>
        {
            if (res.success)
            {
                value = res.data.GetRawJsonValue();
                Debug.Log("Success fetched data : " + value);
                if(value == "")
                {
                    continueSearch = false;
                    Debug.Log(currentID);
                }
            }
            else
            {
                Debug.Log("Fetch data failed : " + res.message);
                continueSearch = false;
            }
        });
    }
    return currentID;
}
情况可能并非如此,在这种情况下,您可能希望将其转换为递归调用。您需要一些函数,如:

public void GetLastUsedID(currentId)
{
        FirebaseREST.DatabaseReference reference = FirebaseREST.FirebaseDatabase.Instance.GetReference(""+currentID);
        reference.GetValueAsync(10, (res) =>
        {
            if (res.success)
            {
                value = res.data.GetRawJsonValue();
                Debug.Log("Success fetched data : " + value);
                if(value == "")
                {
                    continueSearch = false;
                    Debug.Log(currentID);
                }
                else
                {
                    // recurse
                    GetLastID(currentId+1);
                }
            }
            else
            {
                Debug.Log("Fetch data failed : " + res.message);
                continueSearch = false;
            }
        });
}
你必须弄清楚如何将自己的回调传递给读者,让读者知道这样的练习是成功还是失败


最后,我会对你正在做的事情保持谨慎。如果您正在验证用户,我建议您使用直接连接到实时数据库的方法。最多只能在其中存储用户id,并使用以确保只有该用户才能写入。通过使用Firebase身份验证来管理用户数据并将其与RTDB规则绑定,可以避免同样的错误。

请仔细查看您的函数,尤其是while循环和.GetValueAsync,因为我不知道这是否是您想要实现的。GetValueAsync正如名称所指出的那样,异步完成它的工作,第二次调用while循环的主体时,它将重新开始工作。我想这不是你的意图,对吗?我只是想得到数据库中的最后一个数字。在函数中,我获取id1的值。如果返回空字符串,那么我停止整个循环…很好的答案。因此,添加新用户需要主键权限。这就是为什么我仅仅依赖于一个ID变量。有没有更好和/或正确的方法可以做到这一点?RTDB中的主键概念与SQL数据库中的主键概念并不完全相同。您需要某种全局唯一密钥来标识您的条目,您可以使用Firebase身份验证中的用户id,因为您不想使用会话id或任何其他真正应该是私有的。如果您需要生成唯一的密钥,并且顺序无关紧要,那么您可以始终使用Guid.NewGuid并将其缓存在您的PlayerPrefs中:所有这些都不必位于数据库的根目录下。例如,您可以将这些都嵌套在名为users的节点下,而不会导致性能下降。哦,好吧,我的RTDB应该看起来像Unity Project->users->1,2,3…尽管我还没有尝试解决方案,但我会将其标记为正确答案。我在演唱官方firebase时遇到了一些问题,所以我选择了FirebaseREST。我会按照你对官方firebase说的做:谢谢