How to get a Subcollection inside a Collection in Firestore Web Version 9 (Modular)?

Viewed 6044

I was using the chaining mode of the Firestore Web 8, but I'm in the way of updated it to Module 9 and have been a hard time trying to figure out how to get all the content of my subcollection (collection inside my collection).
My older function is like this and works fine:

function getInfo(doc_name) {
    let infoDB = db
      .collection("collection_name")
      .doc(doc_name)
      .collection("subcollection_name")
      .get();

    return alunoHistorico;
  }

so with the module way I tried this code

// Initialize Firebase
const app = initializeApp(firebaseConfig);
const db = getFirestore(app);

const docRef = doc(db, "collection_name", "doc_name");
const docSnap = await getDoc(docRef);

if (docSnap.exists()) {
  console.log("Document data:", docSnap.data());
} else {
  // doc.data() will be undefined in this case
  console.log("No such document!");
}

but the function doc() expects a even arguments (not counting the db argument) so if I try to use with 3 arguments like this, I get a error:

const docRef = doc(db, "collection_name", "doc_name", "subcollection_name");

to it work I have to pass the exactly document that is inside the subcollection

const docRef = doc(db, "collection_name", "doc_name", "subcollection_name", "sub_doc");

but it doesn't work for me because I have a list os docs inside the subcollection, that I want o retrieve. So how can I get all my docs inside my subcollection?

Thanks to anyone who take the time.

2 Answers

You need to use collection() to get a CollectionReference instead of doc() which returns a DocumentReference:

const subColRef = collection(db, "collection_name", "doc_name", "subcollection_name");
// odd number of path segments to get a CollectionReference

// equivalent to:
// .collection("collection_name/doc_name/subcollection_name") in v8

// use getDocs() instead of getDoc() to fetch the collection

const qSnap = getDocs(subColRef)
console.log(qSnap.docs.map(d => ({id: d.id, ...d.data()})))

I wrote a detailed answer on difference between doc() and collection() (in V8 and V9) here:

Firestore: What's the pattern for adding new data in Web v9?

If someone want to get realtime updates of docs inside sub collection using onSnapshot in Modular Firebase V9, you can achieve this like:

import { db } from "./firebase";
import { onSnapshot, collection } from "@firebase/firestore";

let collectionRef = collection(db, "main_collection_id", "doc_id", "sub_collection_id");

  onSnapshot(collectionRef, (querySnapshot) => {
    querySnapshot.forEach((doc) => {
      console.log("Id: ", doc.id, "Data: ", doc.data());
    });
  });
Related