C# 从firestore检索数据时出现问题

C# 从firestore检索数据时出现问题,c#,firebase,unity3d,google-cloud-firestore,C#,Firebase,Unity3d,Google Cloud Firestore,我是firebase的新手,我目前正在unity中进行一个clash of clans克隆人游戏项目。我需要将用户数据(如建筑物位置细节、lvl和其他配置文件细节)放入CloudFireStore。我可以将此详细信息存储到cloud firestore。但我在从中检索数据时遇到了麻烦。我对firestore了解不多,我查看了他们的文档和一些youtube视频,将数据保存到firestore,但我无法检索 DocumentReference docRef = db.Collection("

我是firebase的新手,我目前正在unity中进行一个clash of clans克隆人游戏项目。我需要将用户数据(如建筑物位置细节、lvl和其他配置文件细节)放入CloudFireStore。我可以将此详细信息存储到cloud firestore。但我在从中检索数据时遇到了麻烦。我对firestore了解不多,我查看了他们的文档和一些youtube视频,将数据保存到firestore,但我无法检索

DocumentReference docRef = db.Collection("cities").Document("SF");
docRef.GetSnapshotAsync().ContinueWithOnMainThread(task =>
{
  DocumentSnapshot snapshot = task.Result;
  if (snapshot.Exists) {
    Debug.Log(String.Format("Document data for {0} document:", snapshot.Id));
    Dictionary<string, object> city = snapshot.ToDictionary();
    foreach (KeyValuePair<string, object> pair in city) {
      Debug.Log(String.Format("{0}: {1}", pair.Key, pair.Value));
    }
  } else {
    Debug.Log(String.Format("Document {0} does not exist!", snapshot.Id));
  }
});

DocumentReference docRef=db.Collection(“cities”).Document(“SF”);
docRef.GetSnapshotAsync().ContinueWithOnMainThread(任务=>
{
DocumentSnapshot snapshot=task.Result;
if(snapshot.Exists){
Log(String.Format({0}文档的文档数据:,snapshot.Id));
Dictionary city=snapshot.ToDictionary();
foreach(城市中的KeyValuePair对){
Log(String.Format(“{0}:{1}”,pair.Key,pair.Value));
}
}否则{
Log(String.Format(“文档{0}不存在!”,snapshot.Id));
}
});

这不是我的代码,我是从他们的文档中得到的,我的代码与此类似。我可以调试数据。但是我不能在这个lambda表达式之外使用这个。我需要将数据保存到变量,并像获取建筑物放置详细信息一样使用它(我是一个字符串列表),并在用户玩游戏时使用它来放置建筑物。

就像@DedSec x47所说的那样,似乎同步问题比firestore问题更严重。 需要了解的关键是,当firestore检索数据时,您正在创建一个名为的函数。lambda中的代码不会立即被调用,而是在主线程上检索数据时被调用。问题不在于您从lamda外部访问结果,而是当您访问任务时,还没有从firestore检索的结果

我将研究C#中的async/await模式,它允许您以一种开发者觉得是单线程的方式编写异步代码。我在firebase项目中经常使用这种模式

使用async/await,上述代码可能会变成:

DocumentReference docRef = db.Collection("cities").Document("SF");
DocumentSnapshot snapshot = await docRef.GetSnapshotAsync();
if (snapshot.Exists) 
{
    Debug.Log(String.Format("Document data for {0} document:", snapshot.Id));
    Dictionary<string, object> city = snapshot.ToDictionary();
    foreach (KeyValuePair<string, object> pair in city)
    Debug.Log(String.Format("{0}: {1}", pair.Key, pair.Value));
} 
else
    Debug.Log(String.Format("Document {0} does not exist!", snapshot.Id));

DocumentReference docRef=db.Collection(“cities”).Document(“SF”);
DocumentSnapshot snapshot=await docRef.GetSnapshotAsync();
if(snapshot.Exists)
{
Log(String.Format({0}文档的文档数据:,snapshot.Id));
Dictionary city=snapshot.ToDictionary();
foreach(城市中的KeyValuePair对)
Log(String.Format(“{0}:{1}”,pair.Key,pair.Value));
} 
其他的
Log(String.Format(“文档{0}不存在!”,snapshot.Id));

(尽管outters方法的签名必须更改为
异步任务myMethodName(myParams…)
因此此代码不会像在项目中那样工作。

这听起来是异步加载的任何数据的预期行为:您必须将需要数据的代码放入lambda/回调中,从lambda中调用代码,或者在加载数据后触发UI刷新(如渲染新帧时)@FrankvanPuffelen感谢您的回复…没有其他方法将值保存到变量中吗?我目前没有使用UI元素。我在根据列表放置建筑物时遇到问题。我必须调用建筑物放置函数中的另一个函数来检查该插槽是否可用。因此将该代码放入lambda表达式不起作用,因为我还需要将参数传递给该检查函数。如果我可以保存到变量,或者你可以建议其他方法,那就太好了。值保存到变量中很好,只是在访问变量的代码运行时不会。这是理解异步代码的关键:它不是access问题,这是一个时间问题。嵌套回调是完全可能且有效的,因此这是解决多个调用的一种方法。但在大多数平台上还有其他同步机制,因此我建议也检查这些机制的统一性:。例如,我以前使用过
Task.WaitAll
,但我不确定统一性中是否存在这种机制。