EndpointOS

Connect Firestore

Serve documents from a Firestore collection through an authenticated, logged API.

DocsConnect Firestore

Beta. Credentials are encrypted at rest, but test the connection and start with least-privilege access.

When to use it

A document collection you want readable and writable over a stable HTTP contract, with filtering and paging applied by Firestore itself rather than after the fact.

What to grant

roles/datastore.user on the project, scoped to the database where possible.

Setup

1. Create a service account and grant it access

In the Google Cloud console, create a service account and grant it roles/datastore.user.

gcloud projects add-iam-policy-binding YOUR_PROJECT \
  --member=serviceAccount:endpointos@YOUR_PROJECT.iam.gserviceaccount.com \
  --role=roles/datastore.user

2. Download the key file

Create a JSON key and download it. You paste the whole file, and it is encrypted at rest.

gcloud iam service-accounts keys create key.json \
  --iam-account=endpointos@YOUR_PROJECT.iam.gserviceaccount.com

3. Connect it in EndpointOS

Create a resource, choose Firestore, and enter the project id, the collection, and the key file. Leave the database id blank unless you use a non-default database.

What you will be asked for

  • Google Cloud project id: The project that owns the Firestore database. Find it in the Google Cloud console header, next to the project name.
  • Database id (optional): Optional. Leave blank for the default database, which is what most projects use.
  • Collection: The top-level collection to expose. Documents are read by id from within it.
  • Service account JSON, stored encrypted: Paste the whole key file, starting with '{'. The account needs roles/datastore.user on the project. Stored encrypted.

What the API supports for this source

Generated from the same declaration the API enforces on every request, so it cannot promise something a request would be rejected for.

Filteringequals, not equal, one of, greater than, greater or equal, less than, less or equal on any declared field
SortingAny field you declare. Not createdAt or updatedAt, which this source does not maintain
Search (q)Not supported
Writescreate, update, delete
Paginglimit and offset
Record countApproximate: the total reflects the page

Worth knowing first

  • Filtering runs as a Firestore structured query, so the database applies it rather than us filtering after reading. Equality, not-equal, one-of and the four comparisons are all supported.
  • Firestore needs a composite index for some filter combinations. If a request fails asking for one, the error carries a console link that creates it.
  • Filter values are type-sensitive: Firestore stores 42 and "42" as different values, so a field holding numbers must be declared as a number on the resource or filters will match nothing.
  • Sorting works on your own fields. Be aware of a Firestore rule that surprises people: a document MISSING the field you sort by is left out of the results entirely, so sorting a collection where the field is optional returns fewer rows than not sorting. Without a sort, results are ordered by document id.
  • Comparison filters (greater than, less than, not equal) carry two Firestore rules. Only one field per query can use them, and the results must be ordered by that field first. If you do not send a sort, EndpointOS supplies that ordering for you, so a plain comparison filter just works. If you do send one naming a different field, the request is rejected with a 400 explaining which two fields conflict.
  • createdAt and updatedAt are not sortable here, because Firestore does not maintain them. A request that tries is rejected rather than returning nothing.
  • Record counts are not exact: Firestore does not report a total for a query without a separate aggregation call.

If something goes wrong

FAILED_PRECONDITION, with a request for an index

Why: Firestore needs a composite index for this combination of filters and ordering, and does not create one automatically.

Fix: Follow the console link in the error, which creates the index it wants. The request works once the index finishes building.

A filter returns nothing when you can see matching documents

Why: Firestore compares by type as well as value, so a number filter will not match a field stored as a string.

Fix: Declare the field with the type Firestore actually stores, then filter again.

Sorting returns fewer documents than not sorting

Why: Firestore leaves out any document that does not have the field being sorted by. This is Firestore behaviour, not a filter being applied.

Fix: Sort by a field every document has, or backfill the field on the documents missing it.

Cannot be sorted by createdAt

Why: Firestore does not maintain createdAt or updatedAt, so there is no such field to order by.

Fix: Sort by one of your own fields, or write your own timestamp into each document and sort by that.

A comparison filter is rejected because it does not match the sort

Why: Firestore requires a query using a comparison (greater than, less than, not equal) to be sorted by that same field before any other. Sorting by a different field is not a query Firestore can run.

Fix: Sort by the field you are comparing on, or drop the sort. Without one, EndpointOS orders by the compared field for you.

Two comparison filters on different fields are rejected

Why: Firestore allows comparisons on only one field per query. Ranging over two different fields at once is not supported by the database.

Fix: Compare on one field and narrow the other with an equality filter, or apply the second range in your own code after reading.

Permission denied

Why: The service account lacks roles/datastore.user, or is scoped to a different database.

Fix: Grant roles/datastore.user, and set the database id if you are not using the default database.

Connect Firestore · EndpointOS | EndpointOS