编辑 - 添加新文档时 Firebase 时间戳在 HTML 插值中导致 'Cannot read properties of null' 错误

EDIT - Firebase Timestamp Causing 'Cannot read properties of null' error in HTML interpolation while adding new document

session.startDate 是一个 firebase 时间戳,我在 HTML 中使用 toDate() 函数和日期管道对其进行转换。这非常有效,直到我开始通过服务添加文档。

{{session.startDate.toDate() | date}}

添加新文档后,虽然所有内容都能在屏幕上正确呈现,但我收到大量愤怒的控制台消息:

ERROR TypeError: Cannot read properties of null (reading 'toDate')

因此,我猜测当服务添加文档时,在填充 startDate 之前有足够的时间,因此 .toDate() 函数会失败,直到数据存在。

我确定我要做的事情很简单,我只是不确定我应该在项目中的什么时候等待数据,以及最好的方法。

为此,我使用了 2 个组件:显示组件和服务组件。

显示组件 当显示首次加载时,我获取当前路由 ID,并将 sessionSource 设置为订阅的 sessionService。

ngOnInit(): void {
    this.subscribe = this.activatedRoute.paramMap.subscribe(params => {
      this.pid = params.get('pid');
    })

    this.sessionService.getSessionList(this.pid).subscribe((value) => {
      this.sessionSource = value
    });
  }

然后在HTML,我运行 *ngFor 显示不同文件的列表。

<mat-expansion-panel *ngFor=" let session of sessionSource"
            <mat-expansion-panel-header>
                <mat-panel-title>
                    {{session.startDate.toDate() | date}}
                </mat-panel-title>
                <mat-panel-description>
                    {{session.sessionDescription}}<div *ngIf="session.active">  - Active Session</div>
                </mat-panel-description>
            </mat-expansion-panel-header>
        </mat-expansion-panel>

会话服务 当我使用我的服务添加新会话时,这就是 运行(请注意,有一些正在进行的 'return' 功能可以获取新创建的文档 ID 以用于我还没有的路由还在工作)。

添加新条目成功,并按预期显示在页面上,但出现上述错误。

startNewSession(pid: string){
   return this.afs.collection("/Management/"+pid+"/Sessions").add({
      active: true,
      startDate: firebase.firestore.FieldValue.serverTimestamp(),
      sessionDescription: 'Testing Adding'
    }).then(docRef => {
      return docRef.id
    }).catch(error => console.error("Error adding document: ", error))
  }

好吧,解决方案非常简单,但我花了一段时间才弄清楚问题出在哪里。最后,我回到了我在 medium 上第一次使用 firebase 时间戳时读过的一篇文章。有很多细节,但结果是,在时间戳最终确定之前,它将默认返回一个空值,这就是导致我的空错误的原因。

解决方案是使用“SnapshotOptions”修改每个文档快照,并估计时间戳是多少。我不需要纳秒精度,所以这非常适合我的使用。

最后,我的更改甚至不在我最初发布的内容中,它在服务内部并且是 returns ngOnIt 中对 sessionSource 的订阅。

下面是整个部分,但我所做的只是添加 { serverTimestamps: 'estimate' } 作为 payload.doc.data() 函数的选项。这组是估计的时间戳,我不再有空错误。

 getSessionList(pid: string){

    return this.afs.collection(this.CollectionPath+pid+'/Sessions', ref => ref.orderBy('startDate', 'desc')).snapshotChanges().pipe(
      map(actions => {
        return actions.map(a => {
          const data = a.payload.doc.data({ serverTimestamps: 'estimate' }) as sessions_list;
          const id = a.payload.doc.id;
          return { id, ...data };
        })
      }
      ))
  } 

有一个similar question我在寻找解决方案时发现的