Firestore
Firestore is a NoSQL database with support for realtime updates. It is used as the Illust datastore.
One thing to watch out for with Firestore is that there are different libraries for accessing data on the client (firebase/firestore
), and on the server (`firebase-admin/firestore).
Client
All queries to Firestore from client apps should go through FirebaseCollections
, as this has type information on each collection.
useFirestore
More specifically, React code that queries firestore should generally use the functions defined in useFirestore
. These helpers take a function that takes db
(the FirestoreCollections
), and returns a firestore query to run. When new data comes it, the hook will return the data (with IDs), plus a loading state. You must also pass deps
(like with a useEffect
to re-run the query and re-start the watch.). There are hooks to query for a single doc by ID or query, and a collection as array or dictionary.
Example:
This is generally much simpler to write than code that manually calls onSnapshot
.
For use cases that don't fit with the useFirestore
hooks, you can get a reference to the db
object directly in a hook:
Note that older code may use import { db } from "~/lib/firebase";
. This is a deprecated pattern, as it doesn't mesh well with shared components, SSR, testing, or Storybook.
Non-react code
For non-react code, the fb/query.ts
helpers have the same logic as the useFirestore
hooks. You can get a reference to the FirebaseCollections through
Security Rules
Firestore security rules are stored in firestore.rules
Indexed Queries
In firestore, any query that uses more than one where
or orderBy
clause needs an index. There is a limit of 200 indexes per database, and each index adds some overhead to record creation, so it's important to limit the number of indexes.
Indexes are defined in `firestore.indexes.json`. When adding a new query, check to see if there is already an index for that combination of clauses. If there is not one, you should decide if you can get away with using an existing index and just filtering out some values on the client side. If not, then add a new index to the indexes file before merging. Queries without an index will work in local development, but not when deployed, so this is a manual check.
Warning on removing indexes
If you remove an index, then the next build will fail, as removing an index (or a cloud function) needs an interactive confirmation. You can manually deploy with yarn firebase deploy --only firestore
to deploy the index updates interactively.
API
The API is a trusted environment that runs without Firestore security rules. Queries in API should start with AdminFirestoreCollections
, which holds API-specific versions of the typed collection references.
A configured version of the collections can be imported and used like so:
Last updated