Firestore
Collection Group Queries

Fire Pizza

tl;dr

Firestore Sub-Collections were problem children.

They are very loosely related to their parent documents, so deleting a parent document could orphan an entire sub-collection.

Firestore Collection Group Queries definitively solve this problem by enabling queries across many sub-collections with different parent documents.

Sub-collections are now preferred for many data models.

Long Live Sub-Collections!

Once upon a time, Firestore sub-collections were broken. They were hardly useful.

Then a bunch of ingenious engineers from the Firebase team figured out how to query across sub-collections, no matter how they were nested.

Rejoicing ensued and sub-collections became the go-to data model all across the land!

No, seriously, they were broken.

I wrote an article a year ago where I complained just a little bit about Firestore Sub-Collections.

They weren't that useful.

I mean... they were great for limited use cases where your data could grow in an unbounded way... but you might as well have used top-level collections and tagged your records with their parent document ids.

They looked pretty. That's what I can say about old Firestore sub-collections.

I predicted this. Kind of.

This is garbage. - Chris in 2018

After declaring that sub-collections were garbage—hyperbole for clicks!—I preciently predicted their comeback.

I’m confident that the Firebase team knows of this problem and has some plan to address it, because Firestore is still in beta of course, and I’m thankful to have Firestore even with it’s wacky sub-collection system. - Chris in 2018

And they fixed it!!!

The Firebase team released Firestore Collection Group Queries at Google I/O 2019.

Check out Todd Kerpelman's talk below, or his recent article: Understanding Collection Group Queries in Cloud Firestore

The gist is that you can now query sub-collections no matter which parent documents they live under. The sub-collections have to be named the same and you have to create an index on the Firestore Console.

Collection group queries solve everything

Imagine that you're building a social app where users post their favorite corgi photos.

You can now nest your posts like so: /users/{userId}/corgi-photos/{corgiPhotoId}.

This pattern was broken before, because you couldn't query all of the corgi-photos documents across users. You had to run a separate query for each user.

Now you just type...

const corgiPhotos = db.collectionGroup('corgi-photos');

corgiPhotos.get().then(function(querySnapshot) {
  querySnapshot.forEach(function(doc) {
    console.info(doc.id, ' => ', doc.data());
  });
});

...and you'll need to create a collection group index.

collection group index

Recommendations

Collection Group Queries are pretty intuitive to use. Don't overthink it. They just work.

Opinions/suggestions/hot tips

  • Create your indexes programmatically: see the Firebase docs
  • Nest your sub-collections logically. They get harder to manage if you nest them super deep... so don't go crazy.
  • Don't orphan sub-collections. You can still orphan sub-collections if you delete their parent documents. Orphaned sub-collection documents will show up in collection group queries, but your DB will get messy fast.
  • Tag your sub-collection documents with parent doc ids and timestamps so that they can be filtered and sorted. Collection group queries don't include any information about document parents.

Still need help?

Find me online at firebaseconsulting.com or chrisesplin.com

Email me at chris@chrisesplin.com or find me on Twitter @ChrisEsplin. My DMs are always open!