This should work using FieldPath.documentId()
.
Each document has a hidden __name__
field in its data and this is the target of FieldPath.documentId()
.
For a normal collection query, FieldPath.documentId()
would just be the document's ID. However, for a collection group query, this value is the document's path.
We should be able to use this to find all matching document paths that start with the given city's document path like so:
const cityRef = firebase.firestore().doc('cities/cityId');
firebase.firestore().collectionGroup('attractions')
.orderBy(firebase.firestore.FieldPath.documentId())
.startAt(cityRef.path + "/"),
.endAt(cityRef.path + "/\uf8ff")
.get()
.then((querySnapshot) => {
console.log("Found " + querySnapshot.size + " docs");
querySnapshot.forEach((doc) => console.log("> " + doc.ref.path))
})
.catch((err) => {
console.error("Failed to execute query", err);
})
Edit: While the above code would function if the SDK allowed it, it currently throws an error about having an odd number of segments because of the extra /
.
For now, as long as all your city IDs are the same length (as they would be if using the default docRef.add()
), the below code would function:
const cityRef = firebase.firestore().doc('cities/cityId');
firebase.firestore().collectionGroup('attractions')
.orderBy(firebase.firestore.FieldPath.documentId())
.startAt(cityRef.path),
.endAt(cityRef.path + "\uf8ff")
.get()
.then((querySnapshot) => {
console.log("Found " + querySnapshot.size + " docs");
querySnapshot.forEach((doc) => console.log("> " + doc.ref.path))
})
.catch((err) => {
console.error("Failed to execute query", err);
})
Where the above block fails is if the document ID have different lengths. Let's say you only wanted documents under "/cities/New York"
, if another city called "New Yorkshire"
was also in the cities collection, it would have it's results included too.