Unity C# Firebase: What do I do if "task.Exception.Message" returns "one or more errors have occurred" and is not returning data?

Viewed 687

This is my first time using Firebase with Unity. My code seems to be connected to my Firestore database but is not retrieving the data. I also get this error message: 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) The corresponding line for CloudFirebase.cs:60 is Debug.Log(task); and the code normally gets stuck on is line DocumentSnapshot snapshot = task.Result; System.Threading._ThreadPoolWaitCallback:PerformWaitCallback()

Note: I have tried to look around for answers relating to my issue but can't seem to find any. If you have any links that relate specifically to Unity please do share. Here's my code below:

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");
        }
    });
}
2 Answers

A few notes, which should help you debug:

Exceptions in Task are of type AggregateException. This means that rather than printing out the exception itself with Debug.Log(task.Exception.Message);, you should iterate over the exceptions it contains (usually only 1 in the case of Firebase) and print out each internal exception.

I tend to log these using the Flatten method. Paraphrasing Microsoft's documentation:

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

You could also use Handle. Again paraphrasing the official docs:

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

I suspect that the error will become apparent once you change your code accordingly. But feel free to update the bug with the appropriate exception text if you remain stuck.

Additionally:

  • You shouldn't have to call Task.IsCompleted, this will always be true inside a continuation (see the docs).
  • You shouldn't need to call Task.GetAwaiter, this is intended for the compiler's use (although don't let me stop you if you're doing something creative).
  • You should replace ContinueWith with ContinueWithOnMainThread, this is a Firebase-provided extension method that ensures that continuations run on the main (Unity) thread. You'll immediately run into new and exciting exceptions if you touch almost anything in the UnityEngine namespace in your continuation.
  • My suspicion would be that you have an issue with security rules, but that will become more apparent once you fix your error logging.

I would make sure that the snapshot exist as in the docs:

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

So that the existance of the doc can be discarded as a problem.

I would also tell in the question what is the corresponding line CloudFirebase.cs:60 in your code where you obtain the error and if its not from your code, try to provide the last line called from your code where the error is produced.

Related