0

I have two calls to Firebase: one to get the existing data and one to listen for updates in the data. When those updates happen, instead of replacing the existing data for some reason I see to be adding the two datasets together. Can't figure out why as I'm directly updating state with new data in my second function.

Here are the functions called on mounted():

mounted() {
   this.getImages();
   this.refreshImages();
},

And the two functions in question:

async getImages() {
  let snapshot = await db
    .collection("Maria")
    .orderBy("timestamp", "desc")
    .get();
  snapshot.forEach((doc) => {
    let appData = doc.data();
    appData.id = doc.id;
    this.picturesData.push(appData);
  });
  this.dataLoaded = true;
},
async refreshImages() {
  await db
    .collection("Maria")
    .orderBy("timestamp", "desc")
    .onSnapshot((snapshot) => {
      let newPicturesData = [];
      snapshot.forEach((doc) => {
        let newPictureData = doc.data();
        newPictureData.id = doc.id;
        newPicturesData.push(newPictureData);
      });
      this.picturesData = newPicturesData; // this should overwrite the data in my state, right? But instead it's appending.
    });
},
Renaud Tarnec
  • 79,263
  • 10
  • 95
  • 121
crevulus
  • 1,658
  • 12
  • 42

1 Answers1

1

It's difficult to tell you exactly what's happening without thoroughly testing your code but you have to note that the two calls (to getImages() and refreshImages()) may not be done in the order you expect.

Since in getImages() you push the data to picturesData and in refreshImages() you replace picturesData, I suspect that the listener set through refreshImages() returns data before you get the result of the query triggered by getImages().


Actually, since onSnapshot() triggers an initial call that returns the entire result of the query, you only need to call refreshImages() (you don't need the initial call to getImages()).


Note that onSnapshot() is not an asynchronous method like get(), so you don't need to make refreshImages() async.

Renaud Tarnec
  • 79,263
  • 10
  • 95
  • 121
  • Thanks for your feedback. Can you think of a way I can reverse that process? How can I ensure that the state update in `refreshImages()` happens **after** the first get in `getImages()`? I've removed the async notation from `refreshImages()` but that didn't seem to make a difference. – crevulus Aug 27 '20 at 10:11
  • 1
    Actually, I've just realised that you only need the `refreshImages()` method! (I'm doing several things in parallel and it didn't immediately pop to my head!! :-)). See the updated answer. – Renaud Tarnec Aug 27 '20 at 10:13
  • You may also be interested by this answer: https://stackoverflow.com/a/58276739/3371862 – Renaud Tarnec Aug 27 '20 at 11:38