如何在 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