【问题标题】:Collection subscription returns null on server timestamp集合订阅在服务器时间戳上返回 null
【发布时间】:2022-01-07 10:35:57
【问题描述】:

我在订阅一个名为workReports 的子集合中添加文档。

查询方法:

getWorkReportsByProjectId(projectId: string): Observable<ProjectWorkReport[]> {

  return this.db
    .collection("projects")
    .doc(projectId)
    .collection<ProjectWorkReport>(
      "workReports", 
      ref => ref.where("invalid", "==", false).orderBy("createdAt", "desc")
    )
    .valueChanges({ idField: "id" });
}

创建方法(通知createdAt):

createProjectWorkReport(projectId: string, workReport: ProjectWorkReport): Promise<DocumentReference> {
  return this.db
    .collection("projects")
    .doc(projectId)
    .collection<ProjectWorkReport>("workReports")
    .add({ ...workReport, createdAt: firebase.firestore.FieldValue.serverTimestamp() });
}

我的订阅(我只记录结果):

this.projectsService.getWorkReportsByProjectId(projectId)
  .pipe(takeUntil(this.destroyed$))
  .subscribe((reports) => {
    console.log(reports);
  });

这是正在记录的内容。由于orderBy("createdAt", "desc"),位置0处的元素是新元素,但它的createAt属性为null,但如果在DB上进行更改或再次进行查询,新结果通常具有createdAt(和@987654331 @ 在新的,如果我再创造一个)。

我的猜测是,Firestore 独立于文档的创建考虑了时间戳标记,并且订阅在时间戳设置之前触发。

我做错了吗?如果我的猜测是正确的,我能做些什么来解决?

【问题讨论】:

    标签: angular google-cloud-firestore rxjs angularfire


    【解决方案1】:

    article 可能解释了这种行为。总而言之,它与您所怀疑的相似。 serverTimestamps 不会立即在创建的文档中定义,而是在创建文档后由 Firebase 服务器解析,但会有一点延迟。除了在涉及侦听器时看到null 值之外,这会导致文档创建与您在时间戳上看到的值之间存在非常小的差异:

    然后,当调用 set() 时,侦听器会在写入到达服务器之前立即触发。 SDK 不会将令牌值传递给侦听器。相反,它只是简单地传递 null(目前),因为最终值(还)未知。

    解决时间戳后,您就会开始在 Web 控制台中看到它。此行为有两种解决方法,其中之一是使用 snapshotOptions property 来提供时间戳的即时估计。另一种是使用hasPendingWritesproperty,它可以让您处理如何处理仍待解决的文档。

    同一篇文章深入探讨了服务器时间戳的工作原理,并提供了示例代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-15
      • 2021-07-18
      • 2020-01-03
      • 1970-01-01
      • 2019-02-07
      • 2020-05-27
      • 1970-01-01
      • 2021-08-06
      相关资源
      最近更新 更多