0

So I would like to fill an array with data from firestore, I'm just unsure how to exactly do it.

I have this accessing the user information and data snapshot of items:

auth.onAuthStateChanged(user => {

  if (user) {
    db.collection('items').onSnapshot(snapshot => {
      setupItems(snapshot.docs);
      setupUI(user); 
      userDetails(user);
     }, err =>{
      console.log(err.message);
     })
  } else {
    setupUI();
    setupItems([]);
    userDetails();
  }
}); 

This works in another part of my project to fill in template literals with details from my 'items' collection and also allows me to access the current users UID and their specific document within the users collection.

I currently have this hardcoded:

const products = [
  {
    id: 1,
    img: './cod.jpeg',
    name: 'Call of Duty',
    price: 3,
    cart: false,
    quantity: 1,
    total: 0

  },
  {
    id: 2,
    img: './fonv.jpeg',
    name: 'Fallout:New Vegas',
    price: 4,
    cart: false,
    quantity: 1,
    total: 0
  },
  {
    id: 3,
    img: './ror2.jpeg',
    name: 'Risk of Rain 2',
    price: 5,
    cart: false,
    quantity: 1,
    total: 0

  }
];

I also have the exact same fields in my items collection in firestore i.e. document A has a string field name with apple, string field img with a url, integer field price with a number etc.

Is there a way to make it that for example:

const products = [
{ 

id: filled by firebase,
img: filled by firebase,
name: filled by firebase,
price: filled by firebase,
cart: false,
quantity: 1,
total: 0
}

I know I'd tack on a foreach loop vs coding each item but I'm unsure how to assign the fields vs hardcoding.

EDIT

Upon adding this:

const itemsx = (data) => {
  if (data.length) {

    data.forEach(doc => {
    const item = doc.data();


products = [
  {
    id: item.uid,
    img: item.artwork,
    name: item.gamename,
    price: item.price,
    cart: false,
    quantity: 1,
    total: 0

  }

];
console.log(products)
});
} else {
console.log('If you see this, preschoolers are more competent than you at this point.');
}
}

I get the correct outputs in the console, however, products[] becomes trapped within itemsx and isn't globally accessible anymore. (I added itemsx(snapshot.docs) to the onAuthStateChange method)

I'm doing something horribly wrong, I know I'm doing something horribly wrong, I'm one step forward but now stuck, can anyone see something I can't.

3
  • 1
    i would suggest you make a schema using a class for this to make your life a little easier. (note: i tried to make an answer earlier .... using Flutter/dart .... then i saw the javascript tag lol) Commented Jun 17, 2020 at 4:44
  • @brightknight08 I grabbed the live update of your answer just before it was deleted, I appreciate the detail you went into! Apologies for not making it clear enough in my post :( Commented Jun 17, 2020 at 4:51
  • no it's not your fault. I guess SO can make those tags more visible somehow. Cheers buddy Commented Jun 18, 2020 at 8:43

2 Answers 2

1

There are a couple of ways that you can develop your application to return data from your Firestore into an array. Usually, you will just iterate all the data using a get(), so they are all loaded into an array. For example, like this one below:

let products = this.updates.collection.get()
  .then(querySnapshot => {
    products = querySnapshot.docs.map(doc => doc.data())
  })

As indicated by this answer here, this will return all the documents - the querySnapshot() does that - and save the data into the products array.

Another way, it's using with an await(), to iterate the data into an array. The below code is based in this other answer here, in case you want to check the original one.

const prodRef = db.collection('products');

export const getProducts = async (ids = []) => {
    let products = {};

    try {
        products = (await Promise.all(ids.map(id => prodRef.doc(id).get())))
            .filter(doc => doc.exists)
            .map(doc => ({ [doc.id]: doc.data() }))
            .reduce((acc, val) => ({ ...acc, ...val }), {});

    } catch (error) {
        console.log(`received an error in getUsers method in module \`db/products\`:`, error);
        return {};

    }

    return products;
}

While these codes are untested, I believe they should help you as a starting point for your development.

Let me know if the information helped you

Sign up to request clarification or add additional context in comments.

1 Comment

You were on the right track, thank you for your input! I think I worded my question poorly but you were on the money with the link back to the collection
1

Okay I figured out a workaround for my problem. I was going to delete the question since I figured it out but stack gives me a "It's better if you don't delete" kinda warning so here was my workaround :

var products = [];
const itemsx = (data) => {    
  data.forEach(doc => {
  const item = doc.data();  
products.push({id: item.uid,img: item.artwork,name: item.gamename,price: item.price,cart: false,quantity: 1,total: 0});
});}
console.log(products)

1 Comment

That's nice @Sigh !! Indeed, it's better not to delete it and leave the answer for the Community, so in similar cases, other users can find this helpful. Thanks for providing the workaround! :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.