Unity 在使用 Firebase 数据库进行异步编程时崩溃

Posted

技术标签:

【中文标题】Unity 在使用 Firebase 数据库进行异步编程时崩溃【英文标题】:Unity crashes on async programming with Firebase database 【发布时间】:2019-10-31 06:41:21 【问题描述】:

当我尝试这样做时,它会崩溃:

我想异步获取用户数据,如果我不使用异步任务它返回 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;
    

【问题讨论】:

【参考方案1】:

混合使用 async-await 和阻塞调用可能会导致问题。

参考Async/Await - Best Practices in Asynchronous Programming

如果代码无法一直重构为异步,则使用异步事件处理程序

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

代码也应该遵循异步模式

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;

【讨论】:

以上是关于Unity 在使用 Firebase 数据库进行异步编程时崩溃的主要内容,如果未能解决你的问题,请参考以下文章

使用 Unity 进行 Firebase 电话身份验证

如何使用 DataSnapshot 和 Firebase for Unity?

将 Firebase Admin SDK 添加到 Unity 项目

无法通过 Unity 将数据写入 Firebase 数据库

使用 Unity3d 在 Firebase 中存储 DateTime 值的最佳实践

Unity 中的 Firebase - 禁用持久性