firebase / quickstart-unity

Firebase Quickstart Samples for Unity
https://firebase.google.com/games
Apache License 2.0
835 stars 433 forks source link

Returning TransactionResult.Abort() does not run continuation #205

Closed exzizt closed 6 years ago

exzizt commented 6 years ago

Explained through comments in simplified code example:

DataManager.ModifyCoinsBy(-GameManager.ReviveCostInCoins, task =>
{
    if (!(task.Exception != null || task.IsCanceled || task.IsFaulted || task.Result == null || task.Result.Value == null || !task.Result.Exists || !task.IsCompleted))
    {
        // Success
    }
    else
    {
        // Failure
    }
});

internal static void ModifyCoinsBy(int amount, Action<Task<DataSnapshot>> continueWith = null)
{
    coinsReference.RunTransaction(data =>
    {
        if (Convert.ToInt32(data.Value) + amount >= 0)
        {
            data.Value = Convert.ToInt32(data.Value) + amount;
            return TransactionResult.Success(data);
        }

        // Calling this does not run continueWith.
        return TransactionResult.Abort();
    }).ContinueWith(continueWith);
}
chkuang-g commented 6 years ago

I tried RunTransaction() using latest Firebase SDK (5.2.1) with Unity 2017.3.1 both in editor and on Android. However, I cannot reproduce this issue.

Could you provide the following information?

Thank you, Shawn

exzizt commented 6 years ago

Hi there. I'm using Firebase SDK version 5.2.1, Unity 2018.2.5f1, and running on an Android device (LG G6). I'm also using Mono and .NET 3.5.

chkuang-g commented 6 years ago

Could you try to catch exception in your continuation function?

DataManager.ModifyCoinsBy(-GameManager.ReviveCostInCoins, task =>
{
    Debug.Log("Continuation called!");
    try {
        if (!(task.Exception != null || task.IsCanceled || task.IsFaulted || task.Result == null || task.Result.Value == null || !task.Result.Exists || !task.IsCompleted))
        {
            // Success
        }
        else
        {
            // Failure
        }
    } catch (Exception e) {
        Debug.LogException(e);
    }
});

Long story short, I guess the continuation function actually was called. However, it throws exception when you try to access task.Result.
https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.result?view=netframework-4.7.2

If you do nothing in those "// Success" and "// Failure" block, it should not fail. However, I wonder what is in that "// Failure" block.

Let me know if this work.

Shawn

exzizt commented 6 years ago

@chkuang-g Thanks! I'll try out your suggestion as soon as I can and let you know what I find.

exzizt commented 6 years ago

@chkuang-g Interesting... I commented out my code and the success and failure blocks get called appropriately. So it must be something in my code causing the issue.

EDIT: I have no idea what's changed since, but I put my code back and it works FINE! This is very bizarre. Originally I worked around it by calling an Action method right before TransactionResult.Abort() as a way to fire my required logic, but now it seems to be working normally. Thanks for your time.