C#使用FireSharp读取Firebase返回混合对象与数组JSON的问题
根本原因
Firebase Realtime Database 内置自动数组转换逻辑:当返回对象的所有键均为非负整数字符串,且最大键值小于1024时,Firebase会自动将对象转换为数组,空缺索引位填充null。第一条记录的nearSpots键为3、5,符合转换条件被转成数组;第二条记录的键未达到转换判定阈值,保留原始对象格式,因此出现混合类型返回的问题。
解决方案
方案1:修改键存储格式(最推荐,从根源解决)
给nearSpots的数字键添加固定非数字前缀,例如将3改为spot_3、5改为spot_5,破坏纯数字键的判定条件,Firebase就不会触发自动转数组逻辑,所有nearSpots都会稳定返回对象格式,和预期结构完全一致。
方案2:C#端自定义反序列化兼容
如果无法修改数据库结构,可在反序列化层做兼容处理:
- 若使用Newtonsoft.Json,可编写自定义
JsonConverter自动适配数组和对象两种格式,示例代码如下:
public class NearSpotsConverter : JsonConverter<Dictionary<string, NearSpot>> { public override Dictionary<string, NearSpot> ReadJson(JsonReader reader, Type objectType, Dictionary<string, NearSpot> existingValue, bool hasExistingValue, JsonSerializer serializer) { var result = new Dictionary<string, NearSpot>(); // 处理数组类型 if (reader.TokenType == JsonToken.StartArray) { var arr = JArray.Load(reader); for (int i = 0; i < arr.Count; i++) { if (arr[i].Type != JTokenType.Null) { result.Add(i.ToString(), arr[i].ToObject<NearSpot>(serializer)); } } } // 处理对象类型 else if (reader.TokenType == JsonToken.StartObject) { var obj = JObject.Load(reader); foreach (var prop in obj.Properties()) { result.Add(prop.Name, prop.Value.ToObject<NearSpot>(serializer)); } } return result; } public override void WriteJson(JsonWriter writer, Dictionary<string, NearSpot> value, JsonSerializer serializer) { serializer.Serialize(writer, value); } }
使用时给实体类的nearSpots字段添加特性[JsonConverter(typeof(NearSpotsConverter))]即可自动兼容两种返回类型。
- 若使用System.Text.Json,也可以按照同样逻辑编写自定义
JsonConverter实现兼容。
方案3:切换到Firebase Firestore
如果项目还在早期阶段,可考虑切换到Firestore,Firestore没有自动转数组的强制逻辑,存储结构和返回结构完全一致,不会出现这类类型转换问题。
内容的提问来源于stack exchange,提问作者Emms
相关产品推荐
相关产品推荐

