如何从TypeScript编写的Firebase可调用云函数向Unity发送自定义对象?
解决Firebase可调用函数返回数据在Unity中反序列化卡住的问题
先做核心排查:确认实际返回的JSON结构
不管用哪种序列化方式,先搞清楚Firebase云函数到底返回了什么内容,这是定位问题的关键:
在TypeScript云函数中打印返回的JSON:
export const CreateNewCharacter = functions.https.onCall(async (data, context) => { const resp = new CharactersResponse(); resp.Code = CharactersCode.InvalidName; // 按需设置CharacterID,不需要就留空 console.log("返回的JSON数据:", JSON.stringify(resp)); return resp; });去Firebase控制台的函数日志里查看输出的JSON字符串,确认字段名、值类型是否符合预期。
在Unity中打印收到的原始数据:
不要直接反序列化,先把task.Result.Data转成字符串看真实内容:// 调用云函数后的回调逻辑 if (task.IsCompletedSuccessfully) { string rawJson = JsonConvert.SerializeObject(task.Result.Data); Debug.Log("Firebase返回的原始JSON: " + rawJson); // 再尝试反序列化 // var resp = JsonConvert.DeserializeObject<CharactersResponse>(rawJson); }
针对性解决反序列化问题
1. 修正C#类的序列化配置,匹配TS结构
TS里的CharacterID是可选字段(未赋值时不会出现在JSON中),Unity的C#类要对应处理,同时明确字段映射规则:
using Newtonsoft.Json; public class CharactersResponse : CustomResponse { [JsonProperty("Code")] public CharactersCode Code; // 标记为可选,JSON中无此字段时自动设为null [JsonProperty("CharacterID", NullValueHandling = NullValueHandling.Ignore)] public string CharacterID; } // 确保父类字段兼容无JSON值的情况 public class CustomResponse { [JsonProperty(Required = Required.Default)] public string UnknownErrorMessage = string.Empty; }
2. 放弃JsonConvert,直接解析Firebase返回的字典
Firebase可调用函数返回的Data本质是Dictionary<string, object>,直接解析更可靠,避免序列化冲突:
if (task.IsCompletedSuccessfully) { var dataDict = task.Result.Data as Dictionary<string, object>; if (dataDict == null) { Debug.LogError("返回数据格式错误"); return; } var resp = new CharactersResponse(); // Firebase返回的数字是long类型,需强制转换为枚举 resp.Code = (CharactersCode)(long)dataDict["Code"]; // 处理可选的CharacterID字段 if (dataDict.ContainsKey("CharacterID")) { resp.CharacterID = dataDict["CharacterID"] as string; } // 后续业务逻辑 Debug.Log("解析成功,Code: " + resp.Code); }
3. 规范TS类的实例化方式
TS里用类创建对象时,确保必填字段Code一定被赋值,避免返回不完整的JSON:
export class CharactersResponse { Code: CharactersCode; CharacterID?: string; // 用构造函数强制初始化Code字段 constructor(code: CharactersCode, characterID?: string) { this.Code = code; this.CharacterID = characterID; } } // 使用示例 const resp = new CharactersResponse(CharactersCode.InvalidName);
额外注意点
- 枚举值匹配:确认TS和C#的枚举数字值完全一致(你的代码目前是一致的,没问题);如果TS返回的是枚举字符串(比如"InvalidName"),C#枚举要加
[JsonConverter(typeof(StringEnumConverter))]特性。 - 简化云函数返回:也可以直接返回普通对象替代类实例,比如
return { Code: CharactersCode.InvalidName, CharacterID: null };,避免TS类序列化的潜在问题。
内容的提问来源于stack exchange,提问作者Hellcat8
相关产品推荐
相关产品推荐

