简体   繁体   中英

In Unity how do you call a firebase async function and return the value to a calling function?

I am trying to call Firebase functions inside a "DAL" class as I want to create some abstraction. I cannot figure out how to return a variable from inside the callback, or how to pass in a callback to execute from the controller class I created. How would I make UserExistsInFirebase async and call that from a controller class like

    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;
} 

In your current code the issue is that ContinueWithInMainThread is callback called some time later once the task is finished. In the meantime it doesn't block your UserExistsInFirebase at all which rather directly continues and returns false .

Note btw that a method would need to be async in order to be able to use await within it;)


So instead of ContinueWithInMainThread you would rather make your task async and use await once more.

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;
} 

Now this would then not be returned in the main thread though;)

You can however again ensure that by using eg

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
}    

so basically you have just abstracted the task but keep the handling of the callback on the top level where you are starting your request.


If you still want the error handling like before you could probably also do something like

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;
} 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM