14

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.

Kleber Germano
  • 702
  • 3
  • 10
  • 25

2 Answers2

24

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?

Dharmaraj
  • 47,845
  • 8
  • 52
  • 84
  • 1
    Work fine thank you so much. To anyone who doesn't know how to get the data, I retrieve it using the getDocs() as showed in the documentation, like this: const querySnapshot = await getDocs(collection(db, "collections", "doc_name", "subcollection")); querySnapshot.forEach((doc) => { // doc.data() is never undefined for query doc snapshots console.log(doc.id, " => ", doc.data()); }); Thank you again @Dharmaraj – Kleber Germano Sep 22 '21 at 16:39
  • 1
    You're welcome @KleberGermano. I should have mentioned the `getDocs()` in answer. Thanks :D – Dharmaraj Sep 22 '21 at 16:40
  • In my case I need a query how do I pass that – Patrick Waweru Dec 31 '21 at 10:13
  • @PatrickWaweru it would be best if you post a new question with structure of your database and explaining what query you need to run. – Dharmaraj Dec 31 '21 at 10:17
  • @Dharmaraj I figured it out thanks for the help – Patrick Waweru Jan 05 '22 at 07:20
  • It might be added that additionaly to passing the references seperately, the path to the subcollection as one string like in v8 works as well `const subColRef = collection(db, "collection_name/doc_name/subcollection_name");` – Corrl Jan 05 '22 at 11:30
9

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());
    });
  });
Dharman
  • 30,962
  • 25
  • 85
  • 135
Azhar Zaman
  • 91
  • 1
  • 2