【问题标题】:Adding document in snapshotChanges adds 2 documents在 snapshotChanges 中添加文档会添加 2 个文档
【发布时间】:2018-07-05 18:50:56
【问题描述】:

所以如果查询返回 0 个文档,我会尝试添加一个文档。我已经得到它来创建新文档,但由于某种原因它创建了 2?有没有办法让我限制它只创建一个?

方法如下

this.currentMonth = this.monthCollection.snapshotChanges().map(snapshot => {
  if (snapshot.length <= 0) {
    this.createNewMonth(); <---- THIS GETS CALLED TWICE
  }
  return snapshot.map(doc => {
    const data = doc.payload.doc.data();
    data.id = doc.payload.doc.id;
    this.currentMonthId = doc.payload.doc.id;
    this.currentMonthTotalSpent = doc.payload.doc.data().totalSpent;

    this.expenseCollection = this.monthCollection.doc(doc.payload.doc.id).collection('expenses');
    this.expenses = this.expenseCollection.snapshotChanges().map(snapshot => {
      return snapshot.map(doc => {
        const data = doc.payload.doc.data();
        data.id = doc.payload.doc.id;
        return data;
      });
    });
    return data;
  });
});

编辑:因此,当应用程序打开时,我需要检查 Firestore 是否有一个结束时间戳大于当前时间的月份对象。如果不是这种情况(这意味着它是一个新的月份),我需要创建一个新的月份。我将创建新月份的方法放在下面以供参考。我遇到的问题是创建了 2 个文档,而我只需要一个。

  createNewMonth() {
    let date = new Date(), y = date.getFullYear(), m = date.getMonth();
    let firstDay = new Date(y, m, 1);
    let lastDay = new Date(y, m + 1, 0);

    let newMonth = {
      categories: [],
      endTimestamp: moment(lastDay).unix(),
      name: this.getMonthNameFromTimestamp(moment().unix()),
      startTimestamp: moment(firstDay).unix(),
      totalSpent: 0
    }
    this.monthCollection.add(newMonth);
  }

编辑 2:这里仅供参考,monthCollection

this.monthCollection = this.afs.collection('users').doc(this.auth.getUserId()).collection('months', ref => {
      return ref.where('endTimestamp', '>=', moment().unix()).limit(1);
    });

编辑 3:所以我将签出快照移到另一个检查中,但它仍在创建 2 个文档。您在下面看到的内容高于其他代码。

this.afs.collection('users').doc(this.auth.afAuth.auth.currentUser.uid).collection('months').ref.where('endTimestamp', '>=', moment().unix()).get().then((result) => {
      if (result.empty || result.size <= 0) {
        this.createNewMonth();
      }
    });

【问题讨论】:

  • 请详细描述确切您正在做什么触发此代码,您期望该操作的结果是什么,以及实际发生的事情不是你所期望的。
  • @DougStevenson 我在上面输入了额外的细节!

标签: javascript angular ionic-framework google-cloud-firestore


【解决方案1】:

预计您的快照侦听器会触发两次。

第一时间会给你集合的初始内容。然后,在您的 createNewMonth() 函数中,您将一个新文档添加到同一个集合中。然后,当集合的更新内容(现在包含您刚刚添加的文档)时,快照侦听器将第二次触发。

您应该知道您的侦听器函数接收到的snapshot 上没有length 属性。这不是有效的代码:

if (snapshot.length <= 0) {
  this.createNewMonth();
}

snapshot 是一个 QuerySnapshot 对象。如果您想知道该快照中有多少文档,请使用其size 属性或empty 属性。

另外,如果您不想持续监控集合的此类更改,请考虑在集合引用上使用get(),而不是像现在这样添加侦听器。它会一次性为您提供一组结果。

【讨论】:

  • 所以它说快照是DocumentChangeActionsize/empty 不存在。 length 确实如此
  • 无论 Angular 使用他们的 API 做什么都不会改变这样一个事实,即您的侦听器会被调用两次,一次是初始结果,一次是在您更改集合时。
  • 好的,所以我做了一些更改,但它仍在生成 2 个文档,请您看一下
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-30
  • 1970-01-01
  • 1970-01-01
  • 2020-12-04
  • 1970-01-01
  • 2019-04-08
相关资源
最近更新 更多