Ad

Unity Crashes On Async Programming With Firebase Database

When I try to do this it crashes:

I want to get the user data async, if I don't use async task it returns null

public class Database : MonoBehaviour
{
    private DatabaseReference m_database;

    private const string DATA_URL = "hidden";

    public static Database singleton;

    void Awake ()
    {
        FirebaseApp.DefaultInstance.SetEditorDatabaseUrl(DATA_URL);
        m_database = FirebaseDatabase.DefaultInstance.RootReference;

        DontDestroyOnLoad(this);
        singleton = this;
    }

    void Start ()
    {
        User user = new User();
        user = GetUserAsync("213asdasd").Result;
        Debug.Log(user.email);
    }

    public void RegisterNewUser (User user)
    {
        string jsonData = JsonUtility.ToJson(user);

        m_database.Child("Users").Child(user.id).SetRawJsonValueAsync(jsonData);
        m_database.Child("Users").Child(user.id).Child("id").SetValueAsync(user.id);

        m_database.Child("Users").Child(user.id).Child("email").SetValueAsync(user.email);
    }

    public async Task<User> GetUserAsync (string id)
    {
        User user = new User();
        await FirebaseDatabase.DefaultInstance.GetReference("Users").Child(id)
       .GetValueAsync().ContinueWith(task =>
       {
           if (task.IsFaulted)
           {
               // Handle the error...
           }
           else if (task.IsCompleted)
           {
               DataSnapshot snapshot = task.Result;
               string rawUserData = snapshot.GetRawJsonValue();
               Debug.Log(rawUserData);
               user = JsonUtility.FromJson<User>(rawUserData);
           }
       });

        return user;
    }
}
Ad

Answer

Mixing async-await and blocking calls can cause problems.

Reference Async/Await - Best Practices in Asynchronous Programming

Use an async event handler if the code is unable to be refactored to be async all the way

void Start () {
    started += onStarted;
    started(this, EventArgs.Empty);
}

event EventHandler started = delegate { }
private async void onStarted(object sender, EventArgs  args) {
    started -= onStarted;
    User user = await GetUserAsync("213asdasd");
    Debug.Log(user.email);
}

Also code should follow async all the way pattern

public async Task<User> GetUserAsync (string id) {
    User user = new User();
    try {
        DataSnapshot snapshot = await FirebaseDatabase.DefaultInstance
            .GetReference("Users").Child(id).GetValueAsync();
        string rawUserData = snapshot.GetRawJsonValue();
        Debug.Log(rawUserData);
        user = JsonUtility.FromJson<User>(rawUserData);
    } catch(Exception ex) {
        // Handle the error...
    }
    return user;
}
Ad
source: stackoverflow.com
Ad