Firestore不支持带有自定义原型的JavaScript对象吗?

Jan*_*auw 9 node.js google-bigquery google-cloud-datastore google-cloud-firestore

我正在使用节点Bigquery Package来运行简单的作业。查看工作的结果(例如data),effective_date属性如下所示:

 effective_date: BigQueryDate { value: '2015-10-02' }
Run Code Online (Sandbox Code Playgroud)

这显然是返回data对象中的一个对象。

将返回的json导入Firestore会产生以下错误:

UnhandledPromiseRejectionWarning: Error: Argument "data" is not a 
valid Document. Couldn't serialize object of type "BigQueryDate". 
Firestore doesn't support JavaScript objects with custom prototypes 
(i.e. objects that were created via the 'new' operator).
Run Code Online (Sandbox Code Playgroud)

有没有一种优雅的方式来解决这个问题?是否需要遍历结果并转换/删除所有对象?

Jer*_*yal 7

如果您有FirebaseFirestore.Timestamp对象,请不要使用JSON.parse(JSON.stringify(obj))classToPlain(obj)否则在存储到 Firestore 时会损坏它。

最好还是用{...obj}方法。

firestore
  .collection('collectionName')
  .doc('id')
  .set({...obj});
Run Code Online (Sandbox Code Playgroud)

注意:不要new对文档类中的任何嵌套对象使用运算符,它不起作用。相反,为嵌套对象属性创建一个interfaceor type,如下所示:

firestore
  .collection('collectionName')
  .doc('id')
  .set({...obj});
Run Code Online (Sandbox Code Playgroud)

如果您确实想存储由深度嵌套的更多类对象组成的类对象,那么使用此函数首先将其转换为普通对象,同时保留FirebaseFirestore.Timestamp方法。

interface Profile {
    firstName: string;
    lastName: string;
}

class User {
    id = "";
    isPaid = false;
    profile: Profile = {
        firstName: "",
        lastName: "",
    };
}

const user = new User();

user.profile.firstName = "gorv";

await firestore.collection("users").add({...user});
Run Code Online (Sandbox Code Playgroud)


小智 5

Firestore Node.js客户端不支持自定义类的序列化。

您将在此问题中找到更多说明:
https : //github.com/googleapis/nodejs-firestore/issues/143
“我们明确决定不支持Web和Node.JS客户端的自定义类的序列化”

一种解决方案是将嵌套对象转换为普通对象。例如,使用lodash或JSON.stringify。

firestore.collection('collectionName')
    .doc('id')
    .set(JSON.parse(JSON.stringify(myCustomObject)));
Run Code Online (Sandbox Code Playgroud)

这是相关的文章:
Firestore:将自定义对象添加到数据库

  • 以这种方式使用它可以阻止您设置字段值,例如增量和数组操作! (3认同)

Via*_*lov 5

另一种方法是更少的资源消耗:

firestore
  .collection('collectionName')
  .doc('id')
  .set(Object.assign({}, myCustomObject));
Run Code Online (Sandbox Code Playgroud)

注意:它仅适用于没有嵌套对象的对象。

你也可以使用class-transformer,它是classToPlain()沿exposeUnsetFields选项省略undefined值。

npm install class-transformer
or
yarn add class-transformer
Run Code Online (Sandbox Code Playgroud)
import {classToPlain} from 'class-transformer';

firestore
  .collection('collectionName')
  .doc('id')
  .set(classToPlain(myCustomObject, {exposeUnsetFields: false}));
Run Code Online (Sandbox Code Playgroud)

  • 这对我来说效果更好,因为如果您的自定义对象中有一个日期,firestore 会将其重新编码为时间戳。如果你执行 JSON.stringify() 你的日期将变成一个字符串,这可能是以后的一场噩梦 (3认同)