0

Initial call is:

    db_reference
    .Child("total_users")
    .RunTransaction(RunTransaction)
    .ContinueWithOnMainThread(task => {
        if (task.Exception != null) {
            Debug.Log("Transaction exception.");
        } else if (task.IsCompleted) {
            Debug.Log("Transaction complete.");
        }
    });

Which calls:

TransactionResult RunTransaction(MutableData mutableData) {
    List<object> data = mutableData.Value as List<object>;
    if (data != null) {
        Debug.Log("data not null: " + data);
        // I want to increment data here but mutableData always null       
    } else {
        Debug.Log("data null");
    }
    return TransactionResult.Success(mutableData);
}

Aim is to simply get a value from the mutable data and increment it, however this always returns null and never the data stored in RTDB. Transaction also completes without error other than logging null.

  • Firebase Unity SDK 9.4.0
  • Unity Version: 2021.3.9f1

In addition when I update the value when null:

TransactionResult RunTransaction(MutableData mutableData) {
    List<object> data = mutableData.Value as List<object>;
    if (data != null) {
        Debug.Log("data not null: " + data);
        // I want to increment data here but mutableData always null       
    } else {
        Debug.Log("data null");
        // settings default value as per docs below
        Dictionary<string, object> newData = new Dictionary<string, object>();
        newData["total_users"] = 1;
        mutableData.Value = newData;
    }
    return TransactionResult.Success(mutableData);
}

this does update the value in RTDB successfully BUT this seems to override the actual value stored, which is not coming through and always shows null for the mutableData received.

Any help much appreciated.

FDev
  • 3
  • 3
  • Your first snippet is not changing the data in any way. Is that intentional? --- "completes with error" what is the error message? – Frank van Puffelen Sep 03 '22 at 13:31
  • First snippet is the task manager just logging the outcome of the transaction. – FDev Sep 03 '22 at 21:56
  • @FrankvanPuffelen edited to say 'without' error - my apologies – FDev Sep 03 '22 at 22:03
  • And I meant the *second* snippet, which doesn't change the data in any way. So restarting: your second snippet is not changing the data in any way. Is that intentional? – Frank van Puffelen Sep 03 '22 at 23:05
  • Yes, that second snippet is just trying to see if any data is available / not null. I mentioned below that, I have used the third snippet to update the data and feed that back in as the mutableData which does update successfully. Main issue being it never reads any data and shows null always. – FDev Sep 04 '22 at 00:27
  • Logic will be if null, set first value and if not null increment a value in the data and save that new data however the mutableData is always null. – FDev Sep 04 '22 at 00:27
  • That is the expected behavior. Firebase immediately invoked your callback with its best guess at the current value of the node, which is usually `null`. Even when *you* know that this cannot ever be the value, the SDK can't know that. So your code should handle the `null` (for example by returning an initial value like `0`), and will then be called again once the SDK has gotten the updated current value from the server. – Frank van Puffelen Sep 04 '22 at 04:08

1 Answers1

1

Getting an initial null for the current value is the expected behavior.

Firebase immediately invokes your callback with its best guess at the current value of the node, which is usually null. Even when you know that this cannot ever be the value, the SDK can't know that. So your code should handle the null (for example by returning an initial value like 0), and will then be called again once the SDK has gotten the updated current value from the server.

Also see:

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • But if you get null and set a value how do you prevent it from overriding whatever is in the RTDB with the wrong value? – FDev Sep 04 '22 at 05:43
  • Updated original question to reflect (hopefully) more of what I mean around the null data issue. – FDev Sep 04 '22 at 06:09
  • Firebase will detect the conflict in that situation and retry. Give it a try, so you'll see that it works - and then give my answer and all the links another read (as it's more likely to make sense at that point). – Frank van Puffelen Sep 04 '22 at 14:22
  • Re-tested again - same result. Data never is not null. RunTransaction is called twice. Both times data is null. When null, function updates mutableData to 0 and this overrides the true value in RTDB. Never updates with correct value... – FDev Sep 04 '22 at 22:17
  • To confirm, you would expect first time to be null then the data thereafter yes? – FDev Sep 04 '22 at 22:20
  • "Data never is not null." That makes no difference for how the SDK functions. Usually it won't know the value of the node, so will give you an initial guess of null. You have to return a value, so return what the initial value would be if the data didn't exist yet - or return any random value. It doesn't really matter as long as you return somehting. --- And on your second comment: "Getting an initial `null` for the current value is the expected behavior." ¯\_(ツ)_/¯ – Frank van Puffelen Sep 04 '22 at 22:31
  • Yes, I am returning a value if it is null. That value overrides what is actually on the server. I'm trying to say that it never actually returns data to me at any stage. – FDev Sep 04 '22 at 23:41
  • 1
    Issue in the for me was that the RunTransaction function was failing silently as I checked if mutableData was null or not. – FDev Sep 05 '22 at 06:13