C# 如何从Untiy获得Firebase控制台的最新ID
我有一个与Firebase合作的统一项目,用于谷歌认证。我将用户信息存储在实时数据库中。它们存储为: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,依此类推 但
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说的做:谢谢