If I update a node in Firebase RTDB using Unity with a RunTransaction passing in:
Dictionary<string, object> newData = new Dictionary<string, object>();
newData["key_a"] = "val_a";
newData["key_b"] = "val_b";
newData["key_c"] = "val_c";
mutableData.Value = newData;
With the node already having "key_d" with a value of "val_d" in it. RTDB seems to replace the entire node with the new data passed to it and get rid of "key_d".
My understanding is that "key_a", "key_b", "key_c" would be added but "key_d" would remain on the node.
When I test this in the editor this seems to be true but on real devices, it seems to override the whole node with just "key_a", "key_b", "key_c".
In the Firebase RTDB Security Rules, it states "newData represents the merged result of the new data being written and existing data." which I have some rules based on as well which again work for the editor but not on device.
Namely I validate writes with:
".validate": "newData.hasChildren(['key_a', 'key_b', 'key_c', 'key_d'])"
- Unity: 2021.3.9f1
- Firebase: 9.4.0
Tested on device with no errors, all data posting as normal from editor and device with logging. Tested in RTDB rules playground and data passed in behaves as expected with new keys being added with old keys remaining.
Any help or clarification would be much appreciated.
Edit: additional code:
db_reference
.Child("node")
.RunTransaction(RunTransaction)
.ContinueWithOnMainThread(task => {
if (task.Exception != null) {
Debug.Log("Transaction exception.");
} else if (task.IsCompleted) {
Debug.Log("Transaction complete.");
}
});
TransactionResult RunTransaction(MutableData mutableData) {
List<object> data = mutableData.Value as List<object>;
if (data != null) {
Dictionary<string, object> newData = new Dictionary<string, object>();
newData["key_a"] = "val_a";
newData["key_b"] = "val_b";
newData["key_c"] = "val_c";
mutableData.Value = newData; // this is where the node is overridden and the root of the question / clarification
} else {
Dictionary<string, object> newData = new Dictionary<string, object>();
newData["key_a"] = "val_a";
newData["key_b"] = "val_b";
newData["key_c"] = "val_c";
newData["key_d"] = "val_d";
mutableData.Value = newData;
}
return TransactionResult.Success(mutableData);
}