Angular5报错:DocumentReference.set()数据无效,自定义对象求助
这个报错的核心原因很明确:Firebase的DocumentReference.set()方法只接受普通的JSON可序列化对象,而你传入的PlatformModel是自定义类的实例,它包含了类的原型链、可能的类方法等额外信息,Firebase无法将这些内容序列化成存储所需的格式。
下面给你几个针对性的解决方案,你可以根据自己项目的复杂度选择:
1. 手动转换为普通对象(简单场景首选)
直接从PlatformModel实例中提取需要的属性,构造一个符合PlatformInterface.Root结构的纯对象:
// 假设你的PlatformModel实例是platformModel const plainPlatformData: PlatformInterface.Root = { id: platformModel.id, name: platformModel.name, design: platformModel.design.map(design => ({ primaryColor: design.primaryColor, backgroundImage: design.backgroundImage })), saga: platformModel.saga.map(saga => ({ id: saga.id, name: saga.name, short_desc: saga.short_desc, desc: saga.desc, manga: saga.manga.map(manga => ({...manga})), // 如果Manga也是类实例,同样展开属性 anime: saga.anime.map(anime => ({...anime})) // Anime同理 })) }; // 然后传给set方法 docRef.set(plainPlatformData);
这种方式的好处是完全可控,不会有意外的序列化问题,但如果模型结构复杂,写起来会比较繁琐。
2. 利用JSON序列化快速转换(适合无特殊属性的场景)
如果你的PlatformModel及嵌套对象没有循环引用、Date对象或者自定义方法,可以用JSON.parse(JSON.stringify())快速转成纯对象:
const plainData = JSON.parse(JSON.stringify(platformModel)); docRef.set(plainData);
⚠️ 注意:如果模型里包含Date类型,这种方法会把Date转成字符串;如果有循环引用,会直接报错,所以只适合结构简单的模型。
3. 给模型类添加toJSON方法(自定义序列化逻辑)
在PlatformModel类中实现toJSON方法,定义序列化时要返回的纯对象结构,这样JSON.stringify会自动调用这个方法:
export class PlatformModel implements PlatformInterface.Root { id: string; name: string; design: PlatformInterface.Design[]; saga: PlatformInterface.Saga[]; // 其他类方法... toJSON(): PlatformInterface.Root { return { id: this.id, name: this.name, design: [...this.design], // 如果Design是纯对象直接展开,是类实例的话也要转 saga: this.saga.map(saga => ({ ...saga, manga: [...saga.manga], anime: [...saga.anime] })) }; } }
使用时直接传JSON.stringify后的结果,或者直接用docRef.set(platformModel.toJSON())更高效。
4. 使用类转换库(复杂模型首选)
如果你的项目有很多复杂的自定义模型,推荐使用class-transformer库来处理类实例和纯对象的转换:
首先安装依赖:
npm install class-transformer --save
然后直接用classToPlain方法转换:
import { classToPlain } from 'class-transformer'; // 转换模型实例为纯对象 const plainData = classToPlain(platformModel); docRef.set(plainData);
这个库支持嵌套对象转换、类型保留、自定义序列化规则等,非常适合大型项目。
额外排查点
- 检查嵌套对象:如果
design、saga里的manga、anime也是自定义类的实例,一定要记得把它们也转换成纯对象,否则嵌套的类实例同样会触发报错。 - 确认属性匹配:确保转换后的对象完全符合
PlatformInterface.Root的结构,没有多余的不可序列化属性(比如函数、Symbol类型)。
内容的提问来源于stack exchange,提问作者Budi

