Collection Group Query with Firestore
At Google I/O 2019, Firebase launched a new query type, Collection Group Queries, which can have a major impact on your data modeling decisions. It allows you to combine all subcollections that share the same name, then query them together. Prior to this feature release, it was common to model one-to-many relationships with root collections that contained a field (or foreign key if you will) pointing to the parent document. Root collections are still fine, but this new feature makes it far more practical to organize your data in a natural hierarchy.
In the following lesson, we will look at the basic concepts of Collection Group Queries. Check out the full source code for a more complex threaded comments feature in Angular.
If you have complex data requirements for Firestore, consider enrolling in the full Firestore Data Modeling course.
Collection Group Query
Collection Group Queries are just like regular collection queries, with a few minor caveats to consider.Make sure your project is running Firebase JS version 6.0 or later.
Basic Query
Let’s imagine you have a database where users can comment on posts and reply to comments, leading to a nested structure that looks like this:
posts/{postID}/comments/{commentID}/comments/{commentID}/comments/{commentID}...
A Collection Group Query allows you to join all the collections that share a similar name, in this case comments
, and query across them uniformly.
import * as firebase from 'firebase/app';
const db = firebase.firestore();
const query = db.collectionGroup('comments')
.where('user', '==', 'jeffd23')
.orderBy('createdAt');
Rules
If you have rules enforced in your database, you will need to allow access to the grouped subcollection. You can do this using rules version 2, along with the path=**
syntax.
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
// Allow access to all comments subcollections
match /{path=**}/comments/{id} {
allow read, write;
}
}
}
Index
Collection Group Queries require an index when ordering or filtering by a specific property. If you need an index, you should see an error that looks like this: