Firestore 不支持 JavaScript 个具有自定义原型的对象?
Firestore doesn't support JavaScript objects with custom prototypes?
我正在使用节点 Bigquery Package,来 运行 一个简单的工作。查看作业的结果(比如 data
),effective_date
属性如下所示:
effective_date: BigQueryDate { value: '2015-10-02' }
这显然是返回的 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).
有没有优雅的方法来处理这个问题?是否需要遍历结果并转换/删除所有对象?
firestore Node.js 客户端不支持自定义序列化 类。
您将在本期找到更多解释:
https://github.com/googleapis/nodejs-firestore/issues/143
"We explicitly decided to not support serialization of custom classes for the Web and Node.JS client"
一种解决方案是将嵌套对象转换为普通对象。例如通过使用 lodash 或 JSON.stringify.
firestore.collection('collectionName')
.doc('id')
.set(JSON.parse(JSON.stringify(myCustomObject)));
这是一个相关的 post:
另一种资源消耗较少的方法:
firestore
.collection('collectionName')
.doc('id')
.set(Object.assign({}, myCustomObject));
注意:它仅适用于没有嵌套对象的对象。
您也可以使用 class-transformer
and it's classToPlain()
along with exposeUnsetFields
option 来省略 undefined
个值。
npm install class-transformer
or
yarn add class-transformer
import {classToPlain} from 'class-transformer';
firestore
.collection('collectionName')
.doc('id')
.set(classToPlain(myCustomObject, {exposeUnsetFields: false}));
如果您有 FirebaseFirestore.Timestamp
对象,请不要使用 JSON.parse(JSON.stringify(obj))
或 classToPlain(obj)
,因为它们会在存储到 Firestore 时损坏它。
最好用{...obj}
方法
firestore
.collection('collectionName')
.doc('id')
.set({...obj});
注意:不要对文档 class 中的任何嵌套对象使用 new
运算符,它不会起作用。相反,为嵌套对象属性创建 interface
或 type
,如下所示:
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});
如果你真的想存储 class 对象由深度嵌套的更多 class 对象组成,那么使用这个函数首先将它转换为普通对象,同时保留 FirebaseFirestore.Timestamp
方法。
const toPlainFirestoreObject = (o: any): any => {
if (o && typeof o === "object" && !Array.isArray(o) && !isFirestoreTimestamp(o)) {
return {
...Object.keys(o).reduce(
(a: any, c: any) => ((a[c] = toPlainFirestoreObject(o[c])), a),
{}
),
};
}
return o;
};
function isFirestoreTimestamp(o: any): boolean {
if (o &&
Object.getPrototypeOf(o).toMillis &&
Object.getPrototypeOf(o).constructor.name === "Timestamp"
) {
return true;
}
return false;
}
const user = new User();
user.profile = new Profile();
user.profile.address = new Address();
await firestore.collection("users").add(toPlainFirestoreObject(user));
我正在使用节点 Bigquery Package,来 运行 一个简单的工作。查看作业的结果(比如 data
),effective_date
属性如下所示:
effective_date: BigQueryDate { value: '2015-10-02' }
这显然是返回的 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).
有没有优雅的方法来处理这个问题?是否需要遍历结果并转换/删除所有对象?
firestore Node.js 客户端不支持自定义序列化 类。
您将在本期找到更多解释:
https://github.com/googleapis/nodejs-firestore/issues/143
"We explicitly decided to not support serialization of custom classes for the Web and Node.JS client"
一种解决方案是将嵌套对象转换为普通对象。例如通过使用 lodash 或 JSON.stringify.
firestore.collection('collectionName')
.doc('id')
.set(JSON.parse(JSON.stringify(myCustomObject)));
这是一个相关的 post:
另一种资源消耗较少的方法:
firestore
.collection('collectionName')
.doc('id')
.set(Object.assign({}, myCustomObject));
注意:它仅适用于没有嵌套对象的对象。
您也可以使用 class-transformer
and it's classToPlain()
along with exposeUnsetFields
option 来省略 undefined
个值。
npm install class-transformer
or
yarn add class-transformer
import {classToPlain} from 'class-transformer';
firestore
.collection('collectionName')
.doc('id')
.set(classToPlain(myCustomObject, {exposeUnsetFields: false}));
如果您有 FirebaseFirestore.Timestamp
对象,请不要使用 JSON.parse(JSON.stringify(obj))
或 classToPlain(obj)
,因为它们会在存储到 Firestore 时损坏它。
最好用{...obj}
方法
firestore
.collection('collectionName')
.doc('id')
.set({...obj});
注意:不要对文档 class 中的任何嵌套对象使用 new
运算符,它不会起作用。相反,为嵌套对象属性创建 interface
或 type
,如下所示:
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});
如果你真的想存储 class 对象由深度嵌套的更多 class 对象组成,那么使用这个函数首先将它转换为普通对象,同时保留 FirebaseFirestore.Timestamp
方法。
const toPlainFirestoreObject = (o: any): any => {
if (o && typeof o === "object" && !Array.isArray(o) && !isFirestoreTimestamp(o)) {
return {
...Object.keys(o).reduce(
(a: any, c: any) => ((a[c] = toPlainFirestoreObject(o[c])), a),
{}
),
};
}
return o;
};
function isFirestoreTimestamp(o: any): boolean {
if (o &&
Object.getPrototypeOf(o).toMillis &&
Object.getPrototypeOf(o).constructor.name === "Timestamp"
) {
return true;
}
return false;
}
const user = new User();
user.profile = new Profile();
user.profile.address = new Address();
await firestore.collection("users").add(toPlainFirestoreObject(user));