I am using cloud firestore database to store documents for user inside a next.js application, the collection path is as follows collection "userDocs"-> document "userEmail" -> collection "docs" -> document "documentObject".
I was using firebase v9 sdk and I downgraded to firebase v8 and I am still facing the same issue.
This code snippet is where I add a new document to the database which is done and reflects successfully in the firebase console
db.collection("userDocs").doc(session.user.email).collection("docs").add({
fileName: input,
timestamp: firebase.firestore.FieldValue.serverTimestamp(),
});
when trying to fetch documents from the database I tried the following approaches
1- using react-firebase-hooks
const [snapshot] = useCollectionOnce(
db
.collection("userDocs")
.doc(session?.user.email)
.collection("docs")
.orderBy("timestamp", "desc")
);
2- using firebase query
useEffect(() => {
var query = db.collection("userDocs");
query.get().then((querySnapshot) => {
querySnapshot.forEach((document) => {
document.ref
.collection("docs")
.get()
.then((querySnapshot) => {
console.log(querySnapshot);
});
});
});
This is how I tried to achieve it using firebase v9
import {
collection,
query,
orderBy,
serverTimestamp,
setDoc,
doc,
collectionGroup,
onSnapshot,
getDocs,
} from "firebase/firestore";
useEffect(async () => {
const docRef = query(
collection(db, "UserDocs", session?.user.email, "Docs"),
orderBy("timestamp", "desc")
);
const docSnap = await getDocs(docRef);
const allDocs = docSnap.forEach((doc) => {
console.log(`Document ${doc.id} contains ${JSON.stringify(doc.data())}`);
});
}, []);
CodePudding user response:
I managed to get around this using the following approach:
1- I restructured my database to contain "docs" collection which holds inside a document object that has the following attributes {email, fileName, timestamp} instead of creating a subcollection.
I created the following method to fetch data and map it into a state array to be able to render it
const getDocuments = async () => {
await db
.collection("docs")
.where("email", "==", session?.user.email)
.orderBy("timestamp", "desc")
.get()
.then((res) => {
setUserDocs(res.docs);
})
.catch((error) => {
console.log(error);
});
};
I am still not quite sure why exactly did this attempt work rather than all other trials, but I managed to get things working so far so that's the most important thing for the time being.
CodePudding user response:
The problem was that you were not structuring your data correctly. As shown on the Firebase official documentation Choose a data structure,
when you structure your data in Cloud Firestore, you have a few different options:
- Documents
- Multiple collections
- Subcollections within documents
Consider the advantages of each option as they relate to your use case
Therefore, from the code you've shared in your answer, the structure you're using is Nested data in documents.
I've got a little bit lost on your first approach, but since you've finally got it working, the advice is to structure your data according to what is stated in the documentation and what fits your necessity.
See also