Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firestore: Get subcollection of document found with where

I am trying to get the documents inside an subcollection which is part of an document found with the .where function

Example:

  • RootColl/
  • Doc A/
    • SubColl 1
      • Doc 1
      • Doc 2
      • Doc 3
    • SubColl 2
      • Docs
  • Doc A/
    • SubColl 1
      • Doc 1
      • Doc 2
      • Doc 3
    • SubColl 2
      • Docs

I want to get all the documents under SubColl 1 from the doc with the field level == 1

I am trying to do it like:

db.collection("RootColl").where("field", "==", "1").collection("SubColl 1").get()

But by doing that I get the error

Uncaught TypeError: db.collection(...).where(...).collection is not a function

EDIT 1: By following Frank van Puffelen suggestion, i get the same error, "collection" is not a function

  • Current Code
  • Error
like image 765
dragon blade Avatar asked Dec 04 '17 13:12

dragon blade


People also ask

How do I get specific data from firestore?

There are two ways to retrieve data stored in Cloud Firestore. Either of these methods can be used with documents, collections of documents, or the results of queries: Call a method to get the data. Set a listener to receive data-change events.

Which function is used to fetch data from the firebase document?

The Get() function in Go unmarshals the data into a given data structure. Notice that we used the value event type in the example above, which reads the entire contents of a Firebase database reference, even if only one piece of data changed.


2 Answers

A sub-collection lives under a specific document. A query as you've shared now points to a number of documents. You'll need to execute the query to determine what documents it points to, then loop over the results, and get the sub-collection for each document.

In code:

var query = db.collection("RootColl").where("field", "==", "1");
query.get().then((querySnapshot) => {
  querySnapshot.forEach((document) => {
    document.ref.collection("SubColl 1").get().then((querySnapshot) => {
      ...
    });
  });
});
like image 84
Frank van Puffelen Avatar answered Sep 24 '22 16:09

Frank van Puffelen


With Firebase Version 9 (Sep, 2021 Update):

If subcollection(subcoll) contains 3 documents(doc1, doc2, doc3) like below:

coll > doc > subcoll > doc1 > field1: "value1", field2: "value2"
                       doc2 > field1: "value1", field2: "value2"
                       doc3 > field1: "v1",     field2: "v2"

You can get 2 documents(doc1, doc2) of subcollection(subcoll) with while below:

import { query, collection, where, getDocs } from "firebase/firestore";

const q = query(collection(db, "coll/doc/subcoll"), 
                where("field1", "==", "value1"));
    
const docsSnap = await getDocs(q);

docsSnap.forEach((doc) => {
  console.log(doc.data()); // "doc1" and "doc2"
});

Without forEach() method to get 2 documents(doc1, doc2) of subcollection(subcoll) with while below:

import { query, collection, where, getDocs } from "firebase/firestore";

const q = query(collection(db, "coll/doc/subcoll"),
                where("field1", "==", "value1"));
    
const docsSnap = await getDocs(q);
    
console.log(docsSnap.docs[0].data()); // "doc1"
console.log(docsSnap.docs[1].data()); // "doc2"

In addition, you can get all 3 documents(doc1, doc2, doc3) of subcollection(subcoll) with the code below:

import { getDocs, collection } from "firebase/firestore";

const docsSnap = await getDocs(collection(db,"coll/doc/subcoll"));
      
docsSnap.forEach((doc) => {
  console.log(doc.data()); // "doc1", "doc2" and "doc3"
});

Without forEach() method to get all 3 documents(doc1, doc2, doc3) of subcollection(subcoll) below:

import { getDocs, collection } from "firebase/firestore";

const docsSnap = await getDocs(collection(db, "coll/doc/subcoll"));
        
console.log(docsSnap.docs[0].data()); // "doc1"
console.log(docsSnap.docs[1].data()); // "doc2"
console.log(docsSnap.docs[2].data()); // "doc3"

Again, in addition, you can get only one specific document(doc3) of subcollection(subcoll) with the code below:

import { getDoc, doc } from "firebase/firestore";

const docSnap = await getDoc(doc(db, "coll/doc/subcoll/doc3"));
          
console.log(docSnap.data()); // "doc3"
like image 35
Kai - Kazuya Ito Avatar answered Sep 20 '22 16:09

Kai - Kazuya Ito