firebase onSnapshot how to refresh arrays to avoid duplicate keys?

Viewed 374

here is the code im using to listen to changes in my firestore database:

 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);
  });
});

I'm using vuejs, adding this listener on the mount stage so the arrays depending on this snapshot keep refreshing. but I'm facing a problem which is when changes happen to the database my new snapshot adds the data to the array which results in duplicate keys all over, I can't find an efficient way to reset the arrays on each snapshot before inserting the new version.

id array is an array I use to extract the id then insert it inside the orders array so I can use it internally.

Edit:

 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)

when I reset orders array in callback I get an empty array.

Edit 2- i found the error: I miscalculated where to place the save the array.

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

I should have placed it inside the onSnapshot function so each time it runs I do the save, at first I had in the mounted function right after the onsnapshot listener but I had to reset orders as mentioned in the answer by Frank van Puffelen.

1 Answers

You have two options here:

  • The simplest one is to clear the array every time your callback gets invoked, because doc.docs contains all relevant data to rebuild the UI anyway. So this would be calling orders = [] at the top of the callback.

  • If you want more granular control over updating the UI, you can iterate over doc.docChanges, which allows you to view the changes between the snapshots. So with this you can determine what documents were added to the snapshot (initially that'll be all of them), which ones were removed, and which docs were updated.

Many UI frameworks these days perform minimal updates to the UI based on the data you provide them with, so I'd definitely recommend checking whether that is the case for Vue too before taking the second approach.

Related