Unity C#中Firebase数据序列化与反序列化失败问题排查
问题分析与解决方案
你的反序列化失败核心原因在于类成员的定义方式以及Unity环境下JSON工具的兼容性问题,以下是具体修复步骤:
1. 将自动属性改为公共字段
Unity自带的JsonUtility不支持自动属性({ get; set; }),即使使用Newtonsoft的JsonConvert,在Unity环境下也可能因为属性/字段的差异导致解析异常。把类中的自动属性改为公共字段即可解决基础兼容性问题:
修改PuzzleSphereInformation类:
[Serializable] public class PuzzleSphereInformation { public string creatorName; public List<PuzzleSphereTarget> puzzleSphereTarget; public PuzzleSphereInformation() { this.creatorName = null; this.puzzleSphereTarget = new List<PuzzleSphereTarget>(); } public PuzzleSphereInformation(string creatorName, List<PuzzleSphereTarget> puzzleSphereTarget) { this.creatorName = creatorName; this.puzzleSphereTarget = puzzleSphereTarget; } public string ToJson() { return JsonUtility.ToJson(this); } }
PuzzleSphereTarget类可简化Nullable<float>为float?(功能完全一致):
[Serializable] public class PuzzleSphereTarget { public float? x; public float? y; public float? z; public PuzzleSphereTarget() { this.x = null; this.y = null; this.z = null; } public PuzzleSphereTarget(float xParam, float yParam, float zParam) { this.x = xParam; this.y = yParam; this.z = zParam; } public string ToJson() { return JsonUtility.ToJson(this); } }
2. 统一序列化/反序列化工具
避免混合使用JsonUtility和JsonConvert,选择其中一种保持全程一致:
方案A:全程使用Newtonsoft.Json(推荐)
先通过Unity Package Manager安装com.unity.nuget.newtonsoft-json包,再给类成员添加[JsonProperty]标记明确JSON键与类成员的映射关系:
[Serializable] public class PuzzleSphereTarget { [JsonProperty("x")] public float? x; [JsonProperty("y")] public float? y; [JsonProperty("z")] public float? z; // 构造函数不变 } [Serializable] public class PuzzleSphereInformation { [JsonProperty("creatorName")] public string creatorName; [JsonProperty("puzzleSphereTarget")] public List<PuzzleSphereTarget> puzzleSphereTarget; // 构造函数不变 }
序列化和反序列化统一用JsonConvert:
// 保存逻辑 private void SavePuzzle(string creatorName, List<PuzzleSphereTarget> puzzleTargets) { PuzzleSphereInformation puzzleInfo = new PuzzleSphereInformation(creatorName, puzzleTargets); string puzzleInfoJson = JsonConvert.SerializeObject(puzzleInfo); FirebaseDatabase.DefaultInstance.GetReference($"/community_puzzles/").Push().SetRawJsonValueAsync(puzzleInfoJson); } // 反序列化逻辑 _databaseReference.GetValueAsync().ContinueWithOnMainThread(task => { // 省略Firebase相关代码 foreach (DataSnapshot targetInfo in targetSnapshot.Children) { string puzzleDataJson = targetInfo.GetRawJsonValue(); // 先打印确认JSON字符串内容正确 Debug.Log("Received JSON: " + puzzleDataJson); PuzzleSphereInformation puzzleInformation = JsonConvert.DeserializeObject<PuzzleSphereInformation>(puzzleDataJson); Debug.Log("creatorName: " + puzzleInformation.creatorName); } // 省略Firebase相关代码 });
方案B:全程使用Unity JsonUtility
若坚持用JsonUtility,需注意Unity 2020.1及以上版本才支持Nullable类型,低于该版本需自定义空值处理逻辑。序列化反序列化统一用JsonUtility:
// 保存逻辑 private void SavePuzzle(string creatorName, List<PuzzleSphereTarget> puzzleTargets) { PuzzleSphereInformation puzzleInfo = new PuzzleSphereInformation(creatorName, puzzleTargets); string puzzleInfoJson = JsonUtility.ToJson(puzzleInfo); FirebaseDatabase.DefaultInstance.GetReference($"/community_puzzles/").Push().SetRawJsonValueAsync(puzzleInfoJson); } // 反序列化逻辑 PuzzleSphereInformation puzzleInformation = JsonUtility.FromJson<PuzzleSphereInformation>(puzzleDataJson);
3. 验证数据获取正确性
在反序列化前打印获取到的JSON字符串,确认内容与Firebase中存储的完全一致,排除Firebase数据读取时的层级或转义错误。
内容的提问来源于stack exchange,提问作者Raz781
相关产品推荐
相关产品推荐

