Reputation: 65
I'm trying to run a transaction with realtime database to change an object, with the following code :
void tryBeHost()
{
string path = "weeks/" + week + "/games/" + gameId + "/gameInfo";
_dbRef.Child(path).RunTransaction(mutableData =>
{
GameInfo gameInfo = mutableData.Value as GameInfo;
if (gameInfo == null)
{
gameInfo = new GameInfo();
}
else if (gameInfo.host != null && gameInfo.host != myId)
{
return TransactionResult.Success(mutableData);
}
gameInfo.host = myId;
mutableData.Value = gameInfo;
return TransactionResult.Success(mutableData);
});
}
so I'm getting this weird error :
Exception in transaction delegate, aborting transaction Firebase.Database.DatabaseException: Failed to parse object Serializables.GameInfo ---> System.ArgumentException: Invalid type Serializables.GameInfo for conversion to Variant at Firebase.Variant.FromObject (System.Object o) [0x001df] in Z:\tmp\tmp.EaS8iXpRBh\firebase\app\client\unity\proxy\Variant.cs:117 at Firebase.Database.Internal.Utilities.MakeVariant (System.Object value) [0x00000] in Z:\tmp\tmp.sZ8vrpcx53\firebase\database\client\unity\proxy\Utilities.cs:25 --- End of inner exception stack trace --- at Firebase.Database.Internal.Utilities.MakeVariant (System.Object value) [0x0000d] in Z:\tmp\tmp.sZ8vrpcx53\firebase\database\client\unity\proxy\Utilities.cs:27 at Firebase.Database.MutableData.set_Value (System.Object value) [0x00000] in Z:\tmp\tmp.sZ8vrpcx53\firebase\database\client\unity\proxy\MutableData.cs:136 at InternetShit.b__10_0 (Firebase.Database.MutableData mutableData) [0x00045] in /Users/sandukhan/Unity/projects/Ronda/Assets/Scripts/InternetShit.cs:73 at Firebase.Database.Internal.InternalTransactionHandler.DoTransaction (System.Int32 callbackId, System.IntPtr mutableData) [0x00022] in Z:\tmp\tmp.sZ8vrpcx53\firebase\database\client\unity\proxy\InternalTransactionHandler.cs:49 UnityEngine.Debug:LogWarning(Object) Firebase.Platform.FirebaseLogger:LogMessage(PlatformLogLevel, String) (at Z:/tmp/tmp.BbQyA8B710/firebase/app/client/unity/src/Unity/FirebaseLogger.cs:92) Firebase.LogUtil:LogMessage(LogLevel, String) (at Z:/tmp/tmp.EaS8iXpRBh/firebase/app/client/unity/proxy/LogUtil.cs:68) Firebase.Database.Internal.InternalTransactionHandler:DoTransaction(Int32, IntPtr) (at Z:/tmp/tmp.sZ8vrpcx53/firebase/database/client/unity/proxy/InternalTransactionHandler.cs:51) Firebase.AppUtilPINVOKE:PollCallbacks() Firebase.AppUtil:PollCallbacks() (at Z:/tmp/tmp.EaS8iXpRBh/firebase/app/client/unity/proxy/AppUtil.cs:32) Firebase.Platform.FirebaseAppUtils:PollCallbacks() (at Z:/tmp/tmp.EaS8iXpRBh/firebase/app/client/unity/proxy/FirebaseAppUtils.cs:33) Firebase.Platform.FirebaseHandler:Update() (at Z:/tmp/tmp.BbQyA8B710/firebase/app/client/unity/src/Unity/FirebaseHandler.cs:205) Firebase.Platform.FirebaseMonoBehaviour:Update() (at Z:/tmp/tmp.BbQyA8B710/firebase/app/client/unity/src/Unity/FirebaseMonoBehaviour.cs:45)
my GameInfo Class is the following :
using System;
using Serializables;
namespace Serializables
{
[Serializable]
public class GameInfo
{
public string gameId;
public string host;
public string[] playersIds;
public string[] playersPics;
public string[] playersNames;
}
}
if anyone has an idea to solve this I will be grateful
Upvotes: 1
Views: 1341
Reputation: 3131
I think you figured out the basics: You can only submit bool
, string
, long
, double
, IDictionary
, and List<Object>
to Value
.
There's some interesting notes that I'd like to layer on top of this though! I like to use Unity's JsonUtility
in conjunction with SetRawJsonValueAsync
and GetRawJsonValue
from GetValueAsync
. Your code will look a bit like this:
async void SendGameInfo(string path, GameInfo info) {
try {
await _database
.GetReference(path)
.SetRawJsonValueAsync(JsonUtility.ToJson(info));
Debug.Log($"Successfully wrote {info}");
} catch (AggregateException e) {
Debug.LogWarning($"Failed with {e}");
}
}
async Task<GameInfo> ReadGameInfo(string path) {
try {
var dataSnapshot = await _database
.GetReference(path)
.GetValueAsync();
return JsonUtility.FromJson<GameInfo>(info);
} catch (AggregateException e) {
Debug.LogWarning($"Failed with {e}");
return null;
}
}
Also, if you can, having spent time digging through the library I like to consider IDictionary<string, object>
the "basic primitive" of Realtime Database. This will be used as an intermediary format when you set RawJson if you step through the disassembly. Also, since Transactions
don't provide access to raw json, this will give you a more uniform interface to RTDB (unless your data looks like an array, then your primitive is List<object>
- "looks like" meaning that your keys are numbers and the range of numbers RTDB is aware of is about half full).
Of course, the team actively monitors the quickstart github page and you can use the new "feature request" template to request a change to any of this if it will help 😃.
Upvotes: 1
Reputation: 65
I think RTFM always works, I found out that there are specific types that are accepted for mutableData.Value : bool, string, long, double, IDictionary and List{Object} where Object is one of previously listed types. So I got this error because my class GameInfo is not accepted and I have to convert my object to an IDictionary. source : https://firebase.google.com/docs/reference/unity/class/firebase/database/mutable-data#class_firebase_1_1_database_1_1_mutable_data_1a4833f23246b3079078332d57c5649254
Upvotes: 2