如何在 graphql nest js 中使用 firebase 时间戳?
How to use firebase timestamp with graphql nest js?
firebase 中的所有日期都存储为时间戳,无论您如何存储它们:作为 ISO 字符串,或者只是作为 new Date()
.
但我不想在客户端发送 firestore.Timestamp
实例,所以我需要以某种方式序列化它。
有哪些选择?如何只发送 ISO 字符串或 unix 时间?
1。最简单和最愚蠢的解决方案
使用 unix 时间存储日期:
const newItem = {
...,
createdAt: Date.now(),
};
itemsCollection.add(newItem);
这样它将被存储为普通 number
并且可以使用 new Date()
将其转换回正常日期
2。使用 third-party 库(仅适用于我的模式优先方法)
firestore-graphql-scalars contains scalar firebase 时间戳的类型定义和解析器
如果你打算使用 scheme-first 方法,它工作得很好,但我找不到在 Nest JS GraphQL 代码优先方法中使用它的方法
3。自己定义新的标量类型(代码优先方法实现)
最后我使用代码优先方法想出了这个标量:
@Scalar('FirebaseTimestamp')
export class FirebaseTimestampScalar implements CustomScalar<number, admin.firestore.Timestamp> {
description = 'Firebase timestamp';
parseValue(milliseconds: number): admin.firestore.Timestamp {
return admin.firestore.Timestamp.fromMillis(milliseconds); // value from the client
}
serialize(timestamp: admin.firestore.Timestamp): number {
return timestamp.toMillis(); // value sent to the client
}
parseLiteral(ast: ValueNode): admin.firestore.Timestamp {
if (ast.kind === Kind.INT) {
return admin.firestore.Timestamp.fromMillis(Number(ast.value));
}
return null;
}
}
数据类型:
@ObjectType()
export class DocumentMeta implements IDocumentMeta {
@Field(() => ID)
createdBy: string;
@Field(() => ID)
updatedBy: string;
@Field(() => FirebaseTimestampScalar)
createdAt: Date;
@Field(() => FirebaseTimestampScalar)
updatedAt: Date;
}
P.S。不要忘记将此标量添加到解析器模块提供程序
@Module({
providers: [
...resolvers,
FirebaseTimestampScalar,
],
})
export class ResolversModule {}
你仍然需要在客户端将它转换为日期,但在服务器端它仍然是 Timestamp
实例,所以它看起来更干净一些
5。值得一提,但可能没那么有用
如果您仍然认为需要在 client-side 上获取 Timestamp
'as is',您可以将时间戳对象字符串化,并在客户端解析它
您可以自己做或使用 graphql-type-json
firebase 中的所有日期都存储为时间戳,无论您如何存储它们:作为 ISO 字符串,或者只是作为 new Date()
.
但我不想在客户端发送 firestore.Timestamp
实例,所以我需要以某种方式序列化它。
有哪些选择?如何只发送 ISO 字符串或 unix 时间?
1。最简单和最愚蠢的解决方案
使用 unix 时间存储日期:
const newItem = {
...,
createdAt: Date.now(),
};
itemsCollection.add(newItem);
这样它将被存储为普通 number
并且可以使用 new Date()
2。使用 third-party 库(仅适用于我的模式优先方法)
firestore-graphql-scalars contains scalar firebase 时间戳的类型定义和解析器
如果你打算使用 scheme-first 方法,它工作得很好,但我找不到在 Nest JS GraphQL 代码优先方法中使用它的方法
3。自己定义新的标量类型(代码优先方法实现)
最后我使用代码优先方法想出了这个标量:
@Scalar('FirebaseTimestamp')
export class FirebaseTimestampScalar implements CustomScalar<number, admin.firestore.Timestamp> {
description = 'Firebase timestamp';
parseValue(milliseconds: number): admin.firestore.Timestamp {
return admin.firestore.Timestamp.fromMillis(milliseconds); // value from the client
}
serialize(timestamp: admin.firestore.Timestamp): number {
return timestamp.toMillis(); // value sent to the client
}
parseLiteral(ast: ValueNode): admin.firestore.Timestamp {
if (ast.kind === Kind.INT) {
return admin.firestore.Timestamp.fromMillis(Number(ast.value));
}
return null;
}
}
数据类型:
@ObjectType()
export class DocumentMeta implements IDocumentMeta {
@Field(() => ID)
createdBy: string;
@Field(() => ID)
updatedBy: string;
@Field(() => FirebaseTimestampScalar)
createdAt: Date;
@Field(() => FirebaseTimestampScalar)
updatedAt: Date;
}
P.S。不要忘记将此标量添加到解析器模块提供程序
@Module({
providers: [
...resolvers,
FirebaseTimestampScalar,
],
})
export class ResolversModule {}
你仍然需要在客户端将它转换为日期,但在服务器端它仍然是 Timestamp
实例,所以它看起来更干净一些
5。值得一提,但可能没那么有用
如果您仍然认为需要在 client-side 上获取 Timestamp
'as is',您可以将时间戳对象字符串化,并在客户端解析它
您可以自己做或使用 graphql-type-json