Cloud Firestore GetSnapshotAsync返回一个值。统一与C#
我正试图创建一个类来管理我的CloudFireStore请求(就像任何SQLiteHelper类一样)。但是,firebase使用异步调用,我无法向其他脚本返回值。 下面是一个示例(bool return):Cloud Firestore GetSnapshotAsync返回一个值。统一与C#,c#,firebase,unity3d,asynchronous,C#,Firebase,Unity3d,Asynchronous,我正试图创建一个类来管理我的CloudFireStore请求(就像任何SQLiteHelper类一样)。但是,firebase使用异步调用,我无法向其他脚本返回值。 下面是一个示例(bool return): 不幸的是,由于Firestore充当一些运行缓慢的I/O(磁盘访问或web请求)的前端,因此您与它的任何交互都需要是异步的。在执行此访问时,如果可能的话,您还希望避免阻塞游戏循环。也就是说,不会有对GetSnapshotAsync的同步调用 现在有两种方法可以用来编写感觉同步的代码(如果你
不幸的是,由于Firestore充当一些运行缓慢的I/O(磁盘访问或web请求)的前端,因此您与它的任何交互都需要是异步的。在执行此访问时,如果可能的话,您还希望避免阻塞游戏循环。也就是说,不会有对
GetSnapshotAsync
的同步调用
现在有两种方法可以用来编写感觉同步的代码(如果你像我一样,这样想比回调或反应式结构更容易)
首先是GetSnapshotAsync
返回一个任务。您可以在async
功能中选择等待该任务的wait
:
public async bool CheckIfIsFullyRegistered(string idUtente)
{
DocumentReference docRef = db.Collection("Utenti").Document(idUtente);
// this is equivalent to `task.Result` in the continuation code
DocumentSnapshot snapshot = await docRef.GetSnapshotAsync()
return snapshot.Exists;
}
这一点的关键在于async
/await
对C#object lifecycle做了一些假设,而这些假设在Unity上下文中是无法保证的(更多信息请参阅我的相关文章)。如果您是一名长期的Unity开发人员,或者只是想避免this==null
为真,您可以选择将异步调用包装在WaitUntil
块中:
private IEnumerator CheckIfIsFullyRegisteredInCoroutine() {
string idUtente;
// set idUtente somewhere here
var isFullyRegisteredTask = CheckIfIsFullyRegistered(idUtente);
yield return new WaitUntil(()=>isFullyRegisteredTask.IsComplete);
if (isFullyRegisteredTask.Exception != null) {
// do something with the exception here
yield break;
}
bool isFullyRegistered = isFullyRegisteredTask.Result;
}
我喜欢采用的另一种模式不是检索快照。我将使用来自Firestore(或RTDB)的任何最新数据填充某个Unity端类,并让我的所有Unity对象ping该行为。这特别适合于在每帧的基础上查询数据的任何时候
我希望一切都有帮助 这就是我使用FBDB的方法,但请原谅我的无知,因为我使用FBDB才一周左右 这里是一个片段,我希望它能帮助一些人 创建登录事件的线程任务扩展
static Task DI = new System.Threading.Tasks.Task(LoginAnon);
登录anon
DI = FirebaseAuth.DefaultInstance.SignInAnonymouslyAsync().ContinueWith(result =>
{
Debug.Log("LOGIN [ID: " + result.Result.UserId + "]");
userID = result.Result.UserId;
FirebaseDatabase.DefaultInstance.GetReference("GlobalMsgs/").ChildAdded += HandleNewsAdded;
FirebaseDatabase.DefaultInstance.GetReference("Users/" + userID + "/infodata/nickname/").ValueChanged += HandleNameChanged;
FirebaseDatabase.DefaultInstance.GetReference("Users/" + userID + "/staticdata/status/").ValueChanged += HandleStatusChanged;
FirebaseDatabase.DefaultInstance.GetReference("Lobbies/").ChildAdded += HandleLobbyAdded;
FirebaseDatabase.DefaultInstance.GetReference("Lobbies/").ChildRemoved += HandleLobbyRemoved;
loggedIn = true;
});
然后获取值
DI.ContinueWith(Task =>
{
FirebaseDatabase.DefaultInstance.GetReference("Lobbies/" + selectedLobbyID + "/players/").GetValueAsync().ContinueWith((result) =>
{
DataSnapshot snap2 = result.Result;
Debug.Log("Their nickname is! -> " + snap2.Child("nickname").Value.ToString());
Debug.Log("Their uID is! -> " + snap2.Key.ToString());
//Add the user ID to the lobby list we have
foreach (List<string> lobbyData in onlineLobbies)
{
Debug.Log("Searching for lobby:" + lobbyData[0]);
if (selectedLobbyID == lobbyData[0].ToString()) //This is the id of the user hosting the lobby
{
Debug.Log("FOUND HOSTS LOBBY ->" + lobbyData[0]);
foreach (DataSnapshot snap3 in snap2.Children)
{
//add the user key to the lobby
lobbyData.Add(snap3.Key.ToString());
Debug.Log("Added " + snap3.Child("nickname").Value.ToString() + " with ID: " + snap3.Key.ToString() + " to local lobby.");
currentUsers++;
}
return;
}
}
});
});
DI.ContinueWith(任务=>
{
FirebaseDatabase.DefaultInstance.GetReference(“Lobbies/”+selectedLobbyID+“/players/”).GetValueAsync().ContinueWith((结果)=>
{
DataSnapshot snap2=result.result;
Log(“他们的昵称是!->”+snap2.Child(“昵称”).Value.ToString());
Log(“他们的uID是!->”+snap2.Key.ToString());
//将用户ID添加到我们拥有的大厅列表中
foreach(在OnlineObjes中列出游说数据)
{
Log(“搜索大厅:+lobbyData[0]);
if(selectedLobbyID==lobbyData[0].ToString())//这是承载大厅的用户的id
{
Log(“找到主机游说->”+游说数据[0]);
foreach(snap2.Children中的DataSnapshot snap3)
{
//将用户密钥添加到大厅
添加(snap3.Key.ToString());
Debug.Log(“将ID为“+snap3.Key.ToString()+”的“+snap3.Child(“昵称”).Value.ToString()+”添加到本地大厅”);
当前用户++;
}
返回;
}
}
});
});
显然,您可以随意更改它,它实际上不需要循环,但我正在使用它们进行测试,然后再将代码压缩为可读性较差、更直观的内容。这正是我要搜索的内容。非常感谢帕特里克!(我们是你在youtube和firebase上的忠实粉丝!)太棒了!我喜欢做这些,所以听说它们很有用真是太好了。
DI.ContinueWith(Task =>
{
FirebaseDatabase.DefaultInstance.GetReference("Lobbies/" + selectedLobbyID + "/players/").GetValueAsync().ContinueWith((result) =>
{
DataSnapshot snap2 = result.Result;
Debug.Log("Their nickname is! -> " + snap2.Child("nickname").Value.ToString());
Debug.Log("Their uID is! -> " + snap2.Key.ToString());
//Add the user ID to the lobby list we have
foreach (List<string> lobbyData in onlineLobbies)
{
Debug.Log("Searching for lobby:" + lobbyData[0]);
if (selectedLobbyID == lobbyData[0].ToString()) //This is the id of the user hosting the lobby
{
Debug.Log("FOUND HOSTS LOBBY ->" + lobbyData[0]);
foreach (DataSnapshot snap3 in snap2.Children)
{
//add the user key to the lobby
lobbyData.Add(snap3.Key.ToString());
Debug.Log("Added " + snap3.Child("nickname").Value.ToString() + " with ID: " + snap3.Key.ToString() + " to local lobby.");
currentUsers++;
}
return;
}
}
});
});