Multiple filters in collection views
Firestore is a bit limited when filtering and sorting. limited to a single where clause per query by default.
This means that filtering by multiple fields is not possible out of the box. This is a limitation of Firestore, not of
FireCMS.
Since FireCMS 3.0, if you don’t define indexes manually, FireCMS will attempt to run your query anyway, if it fails it will show a link to the Firestore console to create the required indexes.
If you want to restrict the UI operations that can be performed in a collection, based on your existing indexes, you can
define them in FireCMS, by using a FirestoreIndexesBuilder. This is a builder that allows you to declare your Firestore indexes.
If you define your indexes, FireCMS will only allow you to filter by the fields you have defined, or the fields that can
be filtered and sorted without indexes.
This is an example of how you can define a FirestoreIndexesBuilder.
You can then return an array of indexes that will be used to filter the collection.
import { FirestoreIndexesBuilder } from "@firecms/firebase";
// Sample index builder that allows filtering by `category` and `available` for the `products` collectionconst firestoreIndexesBuilder: FirestoreIndexesBuilder = ({ path }) => { if (path === "products") { // For 2 fields, you need to define 4 indexes (I know...) return [ { category: "asc", available: "desc" }, { category: "asc", available: "asc" }, { category: "desc", available: "desc" }, { category: "desc", available: "asc" } ]; } return undefined;}Adding your indexes in self-hosted FireCMS
Section titled “Adding your indexes in self-hosted FireCMS”import { FirestoreIndexesBuilder, useFirestoreDelegate } from "@firecms/firebase";
// ...
// Sample index builder that allows filtering by `category` and `available` for the `products` collection const firestoreIndexesBuilder: FirestoreIndexesBuilder = ({ path }) => { if (path === "products") { // For 2 fields, you need to define 4 indexes (I know...) return [ { category: "asc", available: "desc" }, { category: "asc", available: "asc" }, { category: "desc", available: "desc" }, { category: "desc", available: "asc" } ]; } return undefined; }
// Delegate used for fetching and saving data in Firestore const firestoreDelegate = useFirestoreDelegate({ // ... firestoreIndexesBuilder });
// ...Adding your indexes in FireCMS Cloud
Section titled “Adding your indexes in FireCMS Cloud”import { FireCMSCloudApp } from "@firecms/cloud";import { FirestoreIndexesBuilder } from "@firecms/firebase";
// Sample index builder that allows filtering by `category` and `available` for the `products` collectionconst firestoreIndexesBuilder: FirestoreIndexesBuilder = ({ path }) => { if (path === "products") { // For 2 fields, you need to define 4 indexes (I know...) return [ { category: "asc", available: "desc" }, { category: "asc", available: "asc" }, { category: "desc", available: "desc" }, { category: "desc", available: "asc" } ]; } return undefined;}
// Add your indexes builder to your appfunction MyApp() {
return <FireCMSCloudApp // ... firestoreIndexesBuilder={firestoreIndexesBuilder} // ... />;}