1

这是我用来监听我的firestore数据库更改的代码:

 async mounted() {
let id = [];
let orders = [];
await db.collection("orders").onSnapshot(doc => {
  includeMetadataChanges: true;

  doc.docs.forEach(x => {
    id.push(x.id);
    let z = Object.assign(x.data(), { id: x.id });
    orders.push(z);
  });
});

我正在使用 vuejs,在挂载阶段添加此侦听器,以便取决于此快照的数组不断刷新。但我面临一个问题,即当数据库发生更改时,我的新快照将数据添加到数组中,这会导致所有重复的键,我找不到在插入之前重置每个快照上的数组的有效方法新版本。

id 数组是我用来提取 id 然后将其插入到 orders 数组中的数组,以便我可以在内部使用它。

编辑:

 async mounted() {
let id = [];
let orders = [];
await db.collection("orders").onSnapshot(doc => {
  includeMetadataChanges: true;
orders = []
id = []
  doc.docs.forEach(x => {
    id.push(x.id);
    let z = Object.assign(x.data(), { id: x.id });
    orders.push(z);
  });
}); 
  
console.log(orders)

当我在回调中重置订单数组时,我得到一个空数组。

编辑2-我发现了错误:我错误地计算了保存数组的位置。

  this.$store.dispatch("mystore/saveOrders", orders);

我应该将它放在 onSnapshot 函数中,因此每次运行时我都会进行保存,起初我在 onsnapshot 侦听器之后的 mount 函数中,但我不得不重置订单,如 Frank van Puffelen 的回答中所述。

4

1 回答 1

2

您在这里有两个选择:

  • 最简单的一种是在每次调用回调时清除数组,因为doc.docs无论如何都包含重建 UI 的所有相关数据。所以这将orders = []在回调的顶部调用。

  • 如果您想要更精细地控制更新 UI,您可以迭代doc.docChanges,这样您就可以查看快照之间的更改。因此,您可以确定哪些文档已添加到快照中(最初将是所有文档)、哪些已删除以及哪些文档已更新。

如今,许多 UI 框架都会根据您提供的数据对 UI 执行最少的更新,因此我绝对建议在采用第二种方法之前检查 Vue 是否也是这种情况。

于 2021-06-14T04:37:10.933 回答