Reputation: 157
I am trying to get all the documents from a Firestore collection. I am following their docs to do so. However, nothing happens. I do not see anything console-logging or any errors whatsoever. Basically, nothing happens, as if the get() function is not working. I am clueless as to what is going on.
Here's the code with the get(). It is written in ReactJS with hooks:
import React, { useState, useEffect } from 'react';
import firebase from '../firebase.js';
import './Messages.css';
function Messages (props) {
const [messages, setMessages] = useState([]);
const [customers, setCustomers] = useState([]);
useEffect(() => {
const query = firebase
.firestore()
.collection("Chats")
.get()
.then((querySnapshot) => {
querySnapshot.forEach((doc) => {
if (doc.exists) {
console.log(doc)
} else {
console.log('nothing')
}
console.log(doc.id, " => ", doc.data());
});
}).catch((error) => {
console.log("Error getting documents: ", error);
});
}, []);
Similarly, the same thing was happening to the onSnapShot function that I tried to use as follows:
useEffect(() => {
const unsub = query.onSnapshot(async querySnapshot => {
if (querySnapshot.docChanges().length > 0) {
const data = querySnapshot.docs.map((doc) => {
return { body: doc.data(), id: doc.id }
}
);
const allData = await Promise.all(data)
setCustomers(allData);
} else { console.log("no data") }
}, (error) => {
console.log("Error listening to documents: ", error);
})
return () => {
unsub();
};
}, []);
The Customers state is empty and console-logging from anywhere within Querysnapshot function does not work. Strangely, however, similar set-ups/codes work in my other components. Adding dependencies or placing the code into another function (fetchData()) and calling it within useEffect did not work. I am also certain it is not an issue with Rules as I am accessing Firestore as an admin for which I have an appropriate Rule set up (match /{documents=**} { allow write, read: if request.auth.token.admin == true; }). I am clueless as to what is going on. Please help.
P.S. The following code does work within the useEffect in the same component, however, but since I can not figure out how to get rid of duplicates that I get from the query in the customers state (tried array.includes and indexof but failed) as I kept getting only one same object, I am ditching the following code in favor of one of the above.
const query = firebase.firestore()
.collectionGroup('Messages')
.orderBy("timestamp", "desc")
const unsub = query.onSnapshot((snapshot) => {
if (snapshot.empty) {
console.log('No matching documents.');
return;
}
snapshot.docs.map((doc) => {
console.log("1")
if (customers.length ) {
console.log("1b")
customers.map((customer) => {
console.log("2")
if (customer.uid.indexOf(doc.data().uid) === -1) {
console.log("3")
setCustomers(prevFiles => ([...prevFiles, {
name: doc.data().name, uid: doc.data().uid
}]))
}
})
} else {
console.log("4")
setCustomers([{name: doc.data().name, uid: doc.data().uid}])
}
});
}, (error) => {
console.log('Error getting messages', error);
})
Upvotes: 2
Views: 3206
Reputation: 157
I figured it out. This might be very useful for somebody who is in a similar situation to know as this does not seem to be explained in the Firestore docs.
Anyways, the reason nothing was happening and console.logging was not working was because the query was empty. So, make sure to always check that your collection has documents which in turn have some information. The documents that I was trying to get contained a collection and named after user ids which I needed. However, since they did not really contain any information, they could not be retrieved. And, I did not know that. I simply needed the names of the documents, the uids.
One way you can check if your snapshot is empty is as follows:
if (snapshot.empty) {
console.log('No matching documents.');
return;
}
In my code, it looks like this:
const query = firebase
.firestore()
.collection("Chats")
.get()
.then((querySnapshot) => {
if (querySnapshot.empty) {
console.log('No matching documents.');
return;
}
querySnapshot.forEach((doc) => {
if (doc.exists) {
console.log(doc)
setCustomers(prevFiles => ([...prevFiles, {
id: doc.data().id, data: doc.data()
}]))
} else {
console.log('nothing')
}
// doc.data() is never undefined for query doc snapshots
console.log(doc.id, " => ", doc.data());
});
}).catch((error) => {
console.log("Error getting documents: ", error);
});
Basically, it will never get to the forEach part if it is empty.
Hope this sheds some light on some confusion that someone might have about the docs in collections. They must contain info to be retrievable. Happy coding.
Upvotes: 2