1

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())}`);
  });
}, []);
Rogelio Monter
  • 1,084
  • 7
  • 18
KarimHesham
  • 111
  • 1
  • 8

2 Answers2

1

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.

KarimHesham
  • 111
  • 1
  • 8
1

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

Rogelio Monter
  • 1,084
  • 7
  • 18
  • Okay, I get the point of data structuring. But, As far as I understand, data structuring is more concerned with my use case for these data. I still don't get exactly why couldn't I fetch data. Was it that my queries do not exactly target the specified document inside the database? or that data structuring could cause issues in serving required data on request? Also, my first approach was fetching data using react-firebase-hooks npm package that integrates react hooks with firebase to provide data access and manipulation throughout the app. – KarimHesham Dec 29 '21 at 04:45
  • 1
    @KarimHesham in fact _it was that your queries do not exactly target the specified document inside the database_ – Rogelio Monter Jan 12 '22 at 18:45