I'm trying to set an array into state, but it doesn't appear to be getting set. I have posted some of my code below.
What I am looking to do is, a user can upload an item to the main collection on firestore, this item will then be shown on the main list, on the main screen.
I also want users to be able to view their own items by they clicking on there own profile and they can see a list of only there items.
I have taken the approach that the item gets uploaded to the main collection on firestore, and then the doc id, and collection reference i.e "c" both get put into a doc in a sub-collection called userItems with is in that specific user's doc. I think this is the best way to do it, so I only have "1 source of truth" and not having to worry about duplicates, especially if I have to update any documents in the future.
As I have said at the top, my problem is the array is empty once I try to iterate through it in the 2nd method "queryUserItems". if someone one would be able to point out what I am doing wrong I would be very grateful, and or if someone might be able to point out a more elegant and efficient way of what I'm ultimately trying to do, that is: saving the items in a way that they can be viewed from the main list as well as the user own list, think of it a bit like how Instagram works.
Thank you for any help :)
UserProfile.js
constructor() {
super();
this.getUserItems = this.getUserItems.bind(this);
this.state = {
Name: '',
Location: '',
items: [],
Keys: [],
test: ''
};
}
componentDidMount() {
console.log('UserProfile');
this.getUserItems();
//this.queryKeys();
}
getUserItems = () => {
const Keys = [];
const userCollectionRef = firebase.firestore()
.collection('a').doc('b')
.collection('c')
userCollectionRef.get()
.then((querySnapshot) => {
console.log("user doc received");
querySnapshot.forEach(function (doc) {
console.log('Doc.id: ', doc.id);
console.log('Doc.Key: ', doc.data().Key);
console.log('Doc.CollectionRef: ', doc.data().CollectionRef);
const {Key, CollectionRef} = doc.data();
Keys.push({
Key,
CollectionRef
})
}); // foreach loop end
this.queryKeys(keys);
}).catch(function (error) {
console.error("getUserItems => error: ", error);
});
// this.setState(() =>({
// Keys,
// test: 'testString'
// }));
console.log("Keys inside: ", Keys);
};
queryKeys(keys) {
const items = [];
console.log("queryKeys Called!");
console.log("queryKeys :", keys);
console.log('test: ', this.test);
keys.forEach(function(Key, CollectionRef) {
console.log("Key array: ", Key);
console.log("CollectionRef array: ", CollectionRef);
firebase.firestore
.collection('a').doc('b')
.collection(CollectionRef)
.doc(Key)
.get().then(function (doc) {
console.log("doc received");
const {Name, imageDownloadUrl, Location} = doc.data();
items.push({
key: doc.id,
doc, // DocumentSnapshot
Name,
imageDownloadUrl,
Location,
});
}).catch(function (error) {
console.error("queryKeys: error: ", error);
})
}) // forEach end
this.setState({
items
});
}
UPDATE:
I have decided to take a different approach, where I just call the queryKeys function at the end of the .then in getUserItems and just pass in the keys as a parameter. this way appears to work as it gets the array in at the right time, but now Im getting an error from firestore:

when I do this :
firebase.firestore
.collection('a').doc('b')
.collection('c')
.doc('docID').get()
.then((doc) => {
How can I get a document by id ?
Thank you
getUserItemsandqueryKeysboth execute asynchronous functions.getUserItemsis setting state afterqueryKeysis called because it fetches data from an external source.getUserItemsshould return a promise or you can useasync/await, but it should return theKeysand then pass them toqueryKeys