mesqueeb / vuex-easy-firestore

Easy coupling of firestore and a vuex module. 2-way sync with 0 boilerplate!
https://mesqueeb.github.io/vuex-easy-firestore
MIT License
233 stars 28 forks source link

Feature: Add firestore.getAll() on the web #355

Closed fergusmeiklejohn closed 3 years ago

fergusmeiklejohn commented 3 years ago

Problem: fetching an array of docs by id

This is a solution using Promise.all() https://medium.com/@cambaughn/firestore-use-promise-all-instead-of-getall-on-the-web-301f4678bd05

This is how I wrote an action to do this:

    getData({ commit }, idArray) {
      const itemRefs = idArray.map(id => {
        return db
          .collection("myCollectionName")
          .doc(id)
          .get();
      });
      Promise.all(itemRefs)
        .then(docs => {
          let data = docs.map(doc => {
            return { ...doc.data(), id: doc.id };
          });
          commit("SET_DATA", data);
        })
        .catch(error => console.log(error));
    }
louisameline commented 3 years ago

Have you tried the fetchAndAdd action? It doesn't work as you'd expect?

fergusmeiklejohn commented 3 years ago

Have you tried the fetchAndAdd action? It doesn't work as you'd expect?

It's not clear in the docs that fetchAndAdd can do this. I have a collection of documents and I'm fetching a subset of them using an array of document IDs. I can't query to fetch them, I only know their IDs. The docs show dispatch('pokemon/fetchById', '001') but can we pass an array of IDs?

louisameline commented 3 years ago

I think it's something like dispatch('pokemon/fetchAndAdd', { clauses: { where: ['id', 'in', ['abc', 'def', 'ghi']] }})

Check the docs and https://firebase.google.com/docs/firestore/query-data/queries#query_operators

fergusmeiklejohn commented 3 years ago

This question on stack overflow discusses it: https://stackoverflow.com/questions/46721517/google-firestore-how-to-get-document-by-multiple-ids-in-one-round-trip We need to use firebase.firestore.FieldPath.documentId() It's limited to 10 items though. Promise.all() is unlimited in theory. I wonder if this would be useful for users:

const idArray = [...]
dispatch('pokemon/fetchById', idArray)
louisameline commented 3 years ago

What's wrong with the solution I gave you

fergusmeiklejohn commented 3 years ago

What's wrong with the solution I gave you

My understanding is that in limits a query to returning maximum 10 documents

louisameline commented 3 years ago

Ok, I didn't know that. For future reference it's limited to 10 parameters in the in clause, not 10 documents technically, but here yes the result is 10 docs.

Implementing a Promise.all is only a few lines but I feel it might be better to let the user handle it and just call by id as many times as required. Some docs might not get retrieved, so you might want to add more code than you've shown to handle this scenario.