【问题标题】:Serialization error with firebase on UnityUnity上firebase的序列化错误
【发布时间】:2021-01-13 06:44:47
【问题描述】:

我正在尝试使用实时数据库运行事务以更改对象,代码如下:

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

    });
}

所以我收到了这个奇怪的错误:

事务委托中的异常,正在中止事务 Firebase.Database.DatabaseException:无法解析对象 Serializables.GameInfo ---> System.ArgumentException:用于转换为 Variant 的类型无效的 Serializables.GameInfo 在 Z:\tmp\tmp.EaS8iXpRBh\firebase\app\client\unity\proxy\Variant.cs:117 中的 Firebase.Variant.FromObject (System.Object o) [0x001df] 在 Z:\tmp\tmp.sZ8vrpcx53\firebase\database\client\unity\proxy\Utilities.cs:25 中的 Firebase.Database.Internal.Utilities.MakeVariant(System.Object 值)[0x00000] --- 内部异常堆栈跟踪结束 --- 在 Z:\tmp\tmp.sZ8vrpcx53\firebase\database\client\unity\proxy\Utilities.cs:27 中的 Firebase.Database.Internal.Utilities.MakeVariant(System.Object 值)[0x0000d] 在 Z:\tmp\tmp.sZ8vrpcx53\firebase\database\client\unity\proxy\MutableData.cs:136 中的 Firebase.Database.MutableData.set_Value(System.Object 值)[0x00000] 在 InternetShit.b__10_0 (Firebase.Database.MutableData mutableData) [0x00045] 在 /Users/sandukhan/Unity/projects/Ronda/Assets/Scripts/InternetShit.cs:73 在 Firebase.Database.Internal.InternalTransactionHandler.DoTransaction (System.Int32 callbackId, System.IntPtr mutableData) [0x00022] 中 Z:\tmp\tmp.sZ8vrpcx53\firebase\database\client\unity\proxy\InternalTransactionHandler.cs:49 UnityEngine.Debug:LogWarning(Object) Firebase.Platform.FirebaseLogger:LogMessage(PlatformLogLevel, String) (在 Z:/tmp/tmp.BbQyA8B710/firebase/app/client/unity/src/Unity/FirebaseLogger.cs:92) Firebase.LogUtil:LogMessage(LogLevel, String) (在 Z:/tmp/tmp.EaS8iXpRBh/firebase/app/client/unity/proxy/LogUtil.cs:68) Firebase.Database.Internal.InternalTransactionHandler:DoTransaction(Int32, IntPtr) (在 Z:/tmp/tmp.sZ8vrpcx53/firebase/database/client/unity/proxy/InternalTransactionHandler.cs:51) Firebase.AppUtilPINVOKE:PollCallbacks() Firebase.AppUtil:PollCallbacks()(在 Z:/tmp/tmp.EaS8iXpRBh/firebase/app/client/unity/proxy/AppUtil.cs:32) Firebase.Platform.FirebaseAppUtils:PollCallbacks()(在 Z:/tmp/tmp.EaS8iXpRBh/firebase/app/client/unity/proxy/FirebaseAppUtils.cs:33) Firebase.Platform.FirebaseHandler:Update()(在 Z:/tmp/tmp.BbQyA8B710/firebase/app/client/unity/src/Unity/FirebaseHandler.cs:205) Firebase.Platform.FirebaseMonoBehaviour:Update()(在 Z:/tmp/tmp.BbQyA8B710/firebase/app/client/unity/src/Unity/FirebaseMonoBehaviour.cs:45)

我的 GameInfo 类如下:


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

如果有人有解决这个问题的想法,我将不胜感激

【问题讨论】:

  • 调试中 mutableData.Value 的值是多少?
  • @DespeiL 是null
  • 所以首先你应该弄清楚为什么你有 null。我无法将 null 解析为某个对象 =0
  • 但如果它是null,我正在创建新的 GameInfo 对象,并且我认为 null 是 firebase 的可解析值(当您要求 firebase 在字段中写入 null 时,它的意思是:删除它)
  • 你不能这样做:mutableData.Value as GameInfo 如果mutableData.Value 为空。在将 mutableData.Value 解析到 GameInfo 之前,请检查 mutableData.Value 是否不为空。如果不解析,则创建 GameInfo 的新对象

标签: c# firebase unity3d firebase-realtime-database serialization


【解决方案1】:

我想你已经弄清楚了基本情况:你只能将boolstringlongdoubleIDictionaryList<Object> 提交给Value

不过,我想在此基础上添加一些有趣的注释!我喜欢将Unity's JsonUtilitySetRawJsonValueAsync 和来自GetValueAsyncGetRawJsonValue 结合使用。你的代码看起来有点像这样:

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

另外,如果可以的话,在花时间挖掘库之后,我喜欢将IDictionary&lt;string, object&gt; 视为实时数据库的“基本原语”。如果您逐步进行反汇编,这将在您设置 RawJson 时用作中间格式。此外,由于Transactions 不提供对原始 json 的访问,这将为您提供更统一的 RTDB 接口(除非您的数据看起来像一个数组,那么您的原语是 List&lt;object&gt; - “看起来像”意味着您的密钥是数字,RTDB 知道的数字范围大约是一半)。

当然,团队会积极监控quickstart github 页面,如果有帮助,您可以使用新的“功能请求”模板来请求更改任何内容 ?。

【讨论】:

  • 但是,正如 OP 也想要的那样,我们可以通过这些助手设置 mutableData 吗?我也在寻找一种在事务中设置 mutableData 的方法,其中值包含不直接支持的类型(例如string[])。目前我正在使用Dictionary&lt;string, object&gt; 方法。我希望有一种方法可以将 rawJson 设置为 mutableData.Value。
【解决方案2】:

我认为 RTFM 始终有效,我发现 mutableData.Value 接受特定类型:bool、string、long、double、IDictionary 和 List{Object},其中 Object 是先前列出的类型之一。所以我收到了这个错误,因为我的类 GameInfo 不被接受,我必须将我的对象转换为 IDictionary。 来源:https://firebase.google.com/docs/reference/unity/class/firebase/database/mutable-data#class_firebase_1_1_database_1_1_mutable_data_1a4833f23246b3079078332d57c5649254

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多