【问题标题】:In Unity how do you call a firebase async function and return the value to a calling function?在 Unity 中,如何调用 firebase 异步函数并将值返回给调用函数?
【发布时间】:2022-02-17 14:48:36
【问题描述】:

我想在“DAL”类中调用 Firebase 函数,因为我想创建一些抽象。我无法弄清楚如何从回调内部返回变量,或者如何传入回调以从我创建的控制器类中执行。我如何使 UserExistsInFirebase 异步并从控制器类中调用它,例如

    public void GetUser() {
        bool exists = await firebase.UserExistsInFirebase("User1");
    }    
public Task<bool> UserExistsInFirebase(string Username)
{
   bool isExists = false;
    reference.Child("Users").Child(Username).Child("Username").Child(Username).GetValueAsync().ContinueWithOnMainThread(task =>
    {
        if (task.IsCompleted)
        {
            DataSnapshot snapshot = task.Result;
            //checks to see if we found another user with the same username
            if (snapshot.GetValue(true) != null)
            {
                isExists = true;
            }
        }
    });
    return isExists;
} 

【问题讨论】:

    标签: c# unity3d firebase-realtime-database


    【解决方案1】:

    在您当前的代码中,问题是ContinueWithInMainThread 在任务完成后的某个时间后被回调。与此同时,它根本不会阻止您的UserExistsInFirebase,而是直接继续并返回false

    注意顺便说一句,方法必须是 async 才能在其中使用 await ;)


    因此,您宁愿将任务设为async 并再次使用await,而不是ContinueWithInMainThread

    public async Task<bool> UserExistsInFirebase(string Username)
    {
        var snapShot = await reference.Child("Users").Child(Username).Child("Username").Child(Username).GetValueAsync();
    
        return snapShot.GetValue(true) != null;
    } 
    

    现在这不会在主线程中返回;)

    但是,您可以再次确保通过使用例如

    public void GetUser() 
    {
        firebase.UserExistsInFirebase("User1").ContinueWithOnMainThread(exists => 
        {
            // Do something with the bool exists after the request has finished
        });
    
        // again anything here would be immediately executed before the request is finihed
    }    
    

    所以基本上你只是抽象了任务,但将回调的处理保持在你开始请求的顶层。


    如果你仍然想要像以前一样的错误处理,你可能还可以做类似的事情

    public async Task<bool> UserExistsInFirebase(string Username)
    {
        bool isExists = false;
        await  reference.Child("Users").Child(Username).Child("Username").Child(Username).GetValueAsync().ContinueWith(task =>
        {
            if (task.IsCompleted)
            {
                DataSnapshot snapshot = task.Result;
                //checks to see if we found another user with the same username
                if (snapshot.GetValue(true) != null)
                {
                    isExists = true;
                }
            }
        });
        return isExists;
    } 
    

    【讨论】:

    • 这是一个很好的解释,对我来说完全有意义。我遇到return task.IsCompleted &amp;&amp; task.Result.GetValue(true) != null;line 的问题,Firebase 异步调用 GetValueAsync() 正在返回一个 DataSnapshot 对象,该对象是任务。所以 task.IsCompleted 错误说 IsCompleted 不是 DatabaseSnapshot 的一部分。看起来它应该返回 Task 但是如果我尝试以这种方式声明任务而不是使用像 Task = await 引用这样的 var ......它仍然会出错,说不能将 Task 隐式转换为 DatabaseSnapshot。非常感谢您的帮助!
    • @Kris 你是对的,await 已经返回结果值,而不是任务。我认为虽然ContinueWith 实际上返回了一个新任务,但您仍然可以在使用回调时等待
    • 这项工作我可以直接在回调中访问返回值。感谢您的帮助,这为我解决了很多令人头疼的问题!
    猜你喜欢
    • 1970-01-01
    • 2017-10-18
    • 2019-02-27
    • 2018-01-03
    • 1970-01-01
    • 2023-04-04
    • 2011-07-26
    • 1970-01-01
    • 2021-02-10
    相关资源
    最近更新 更多