如何在应用程序模型中使用FieldValue.serverTimestamp

时间:2018-03-06 18:09:37

标签: typescript firebase google-cloud-firestore

在我的Typescript应用程序代码中,我定义了一个模型,该模型使用Firestore在服务器上生成的时间戳。当文档从数据库返回时,该字段将是ISO字符串。我希望在我的应用程序中使用相同的模型定义来编写和读取数据,但这会产生问题。

我通常会这样写:

interface Document {
  title: string,
  createdAt: string
}

async function addDocument(document: Document): Promise<string> {
  const id = await firestore.collection('documents').add(someDocument)
  return id
}

async function getDocumentData(documentId: string): Promise<Document> {
  const doc = await firestore.collection('documents').doc(documentId).get()

  invariant(doc.exists, `No document available with id ${documentId}`)
  return doc.data() as Document
}

const someDocument: Document = {
  title: "How to",
  createdAt: firestore.FieldValue.serverTimestamp()
}

const newDocumentId = await addDocument(someDocument)

现在,Typescript编译器抱怨someDocument的值不兼容,因为createdAt被定义为字符串。

之前,我通过诱使编译器相信它是createdAt: firestore.FieldValue.serverTimestamp() as string的字符串来攻击这个。

随着最近对Typescript的更新,这个容差似乎已经消失,我正在使用严格的设置。编译器现在告诉我:

  

类型'FieldValue'无法转换为'string'类型。

我不知道再次解决编译器问题,我想知道处理这个问题的正确方法是什么?

- 编辑 -

由于Firestore时间戳行为的即将发生的变化,我再次看到这一点,我发现API实际上并没有返回ISO字符串而是返回Date对象。因为Date对象具有自动字符串转换,所以我的代码始终有效,但在这种意义上类型定义不正确。这不会改变我最初的问题。

1 个答案:

答案 0 :(得分:1)

Firebase的新行为是从db方法返回Timestamp对象,而不是Date对象。

在我的类型定义文件中,我现在导入Timestamp类型(你需要使用Typescript 2.9),然后在我的模型中使用它:

export type FirestoreTimestamp = import("firebase").firestore.Timestamp;

export interface LockableItem {
  isLocked: boolean;
  lockedBy?: UserId;
  lockedAt?: FirestoreTimestamp;
}

使用FieldValue设置lockedAt字段时,您现在可以执行以下操作:

const item: LockableItem = { 
  isLocked: true,
  lockedAt: FieldValue.serverTimestamp() as FirestoreTimestamp, 
  lockedBy: "someuser" 
}