Unity C# Firebase:如果“task.Exception.Message”返回“发生了一个或多个错误”并且没有返回数据,我该怎么办?

Posted

技术标签:

【中文标题】Unity C# Firebase:如果“task.Exception.Message”返回“发生了一个或多个错误”并且没有返回数据,我该怎么办?【英文标题】:Unity C# Firebase: What do I do if "task.Exception.Message" returns "one or more errors have occurred" and is not returning data? 【发布时间】:2021-07-20 08:38:50 【问题描述】:

这是我第一次将 Firebase 与 Unity 一起使用。我的代码似乎已连接到我的 Firestore 数据库,但没有检索数据。 我也收到此错误消息:System.Threading.Tasks.ContinuationResultTaskFromResultTask2[Firebase.Firestore.DocumentSnapshotProxy,Firebase.Firestore.DocumentSnapshot] UnityEngine.Debug:Log(Object) <>c:<savedata>b__5_0(Task1) (at Assets/Scripts/CloudFirebase.cs:60) CloudFirebase.cs:60 的对应行是Debug.Log(task);,代码通常卡在行DocumentSnapshot snapshot = task.Result; System.Threading._ThreadPoolWaitCallback:PerformWaitCallback()

注意:我试图四处寻找与我的问题相关的答案,但似乎找不到任何答案。如果您有任何与 Unity 相关的链接,请分享。 下面是我的代码:

FirebaseFirestore db;
Dictionary<string, object> user;
CollectionReference stuRef;


private bool istrue = true;
// Start is called before the first frame update
void Start()

    Debug.Log("Start called");
    Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task => 
        var dependencyStatus = task.Result;
        if (dependencyStatus == Firebase.DependencyStatus.Available)
        
            Debug.Log("available for use");
            // Create and hold a reference to your FirebaseApp,
            // where app is a Firebase.FirebaseApp property of your application class.
            //app = Firebase.FirebaseApp.DefaultInstance;
            db = FirebaseFirestore.DefaultInstance;
            Debug.Log(db.Collection("Users").Document("hello"));
            stuRef = db.Collection("Users");
            savedata();
            // Set a flag here to indicate whether Firebase is ready to use by your app.
        
        else
        
            UnityEngine.Debug.LogError(System.String.Format(
              "Could not resolve all Firebase dependencies: 0", dependencyStatus));
            // Firebase Unity SDK is not safe to use here.
        
    );
    //db = FirebaseFirestore.DefaultInstance;
    //if (istrue)
    //
    //    savedata();
    //    istrue = false;
    //


public void savedata()


    
    stuRef.Document("hello").GetSnapshotAsync().ContinueWith(task =>
    
        if (task.IsCompleted)
        
            task.GetAwaiter();
            if (task.IsFaulted)
            
                Debug.Log(task.Exception.Message);
               
            
            Debug.Log("succesfully added to database");
            Debug.Log(task);

            DocumentSnapshot snapshot = task.Result;
            if (snapshot.Exists)
                
                Debug.Log("snapshot exists");
                //user = snapshot.ToDictionary();
                //    foreach (KeyValuePair<string, object> pair in user)
                //    
                //        Debug.Log(("0:1", pair.Key, pair.Value));
                //    
            
            else
            
                Debug.Log("snapshot does not exist");
            
            
        
        else
        
            Debug.Log("failed db");
        
    );

【问题讨论】:

【参考方案1】:

一些注意事项,应该可以帮助您调试:

Task 中的Exceptions 属于AggregateException 类型。这意味着,与其使用Debug.Log(task.Exception.Message); 打印出异常本身,不如迭代它包含的异常(在 Firebase 的情况下通常只有 1 个)并打印出每个内部异常。

我倾向于使用Flatten 方法记录这些。转述Microsoft's documentation:

foreach (var e in task.Exception.Flatten().InnerExceptions) 
    Debug.LogWarning($"Received Exception: e.Message");

您也可以使用Handle。再次解释official docs:

task.Exception.Handle(e => 
    Debug.LogWarning($"Received Exception: e.Message");
);

我怀疑一旦您相应地更改代码,错误就会变得明显。但是,如果您仍然卡住,请随时使用适当的异常文本更新错误。

另外:

您不必调用Task.IsCompleted,这在延续中总是如此(请参阅the docs)。 您不需要调用Task.GetAwaiter,这是供编译器使用的intended(尽管如果您正在做一些有创意的事情,请不要让我阻止您)。 您应该将ContinueWith 替换为ContinueWithOnMainThread,这是一个Firebase-provided extension method,可确保继续在主(Unity)线程上运行。如果您在 continuation 中触及 UnityEngine 命名空间中的几乎所有内容,您将立即遇到令人兴奋的新异常。 我怀疑您的 security rules 存在问题,但一旦您修复了错误日志记录,问题就会变得更加明显。

【讨论】:

我在代码中添加了 Flatten 方法并得到了这个输出 => 收到的异常:缺少权限或权限不足。 UnityEngine.Debug:LogWarning(Object) 我查找了此错误并找到了解决方案,感谢您的帮助【参考方案2】:

我会确保快照存在于文档中:

DocumentReference docRef = db.Collection("Users").Document("hello");
DocumentSnapshot snapshot = await docRef.GetSnapshotAsync();
if (snapshot.Exists)
 
    //whatever
 else

Console.WriteLine("Document 0 does not exist!", snapshot.Id);

这样文档的存在就可以作为问题被丢弃。

我还将在问题中告诉您在代码中获得错误的对应行 CloudFirebase.cs:60 是什么,如果它不是来自您的代码,请尝试提供从您的代码中调用的最后一行产生错误。

【讨论】:

对应的行 CloudFirebase.cs:60 是这个“Debug.log(task)”并且通常卡在“DocumentSnapshot snapshot = task.Result;”上 这行代码不起作用 "DocumentSnapshot snapshot = await docRef.GetSnapshotAsync();"

以上是关于Unity C# Firebase:如果“task.Exception.Message”返回“发生了一个或多个错误”并且没有返回数据,我该怎么办?的主要内容,如果未能解决你的问题,请参考以下文章

Google Firebase 和 Unity (C#):无法从存储桶下载 png

Unity 中的 Google Firebase 身份验证:如何读取错误代码

将 Firebase Admin SDK 添加到 Unity 项目

从 Firebase 中的实时数据库获取数据后,无法写入 Unity 的 TMPro 文本字段

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

Firebase Unity 密码验证失败