Query Firestore from the Simple GUI Tool

Query Firestore from the Simple GUI Tool

Get the most out of Firebase by using the Firefoo query tool to query your Firestore data!
default
The capabilities of Firefoo exceed the native Firebase Console:
  • Multiple where conditions and order by clauses
  • Where and order by on different fields
  • Field auto-complete, also for nested fields
  • Additional starts-with operator
  • Save queries for fast access
  • View results as Table, Tree and JSON
  • Export results to JSON and CSV
  • Preview Geopoints on map
See for yourself!

Where Conditions

Where conditions with an empty field value are ignored. Use the (+) button to create a new condition line. The operator can be one of the default Firestore operators <, <=, ==, >, >=, !=, array-contains, array-contains-any, in, not-in, as well as the additional starts-with operator.
Keep in mind that Firestore does not return documents without a field for which a where condition exists. This can be counter-intuitive, take the example query condition name != "Julia". Documents that do not have a name field at all will not be part of the results! Docs with a name of null (Firestore null type) will be part of the results though! This also means that it's impossible to write a condition to reveal all docs that are missing a specific field. You can write a JS script to retrieve all documents and loop over them locally though.
The order of where conditions does not matter when querying Firestore. Firebase has strict limitations on which queries are allowed, e.g. there cannot be two not-equals (!=) conditions in one query, read more below.
Queries with where or order-by clauses on different fields need a composite index. When you try to run the query in Firefoo, you'll see an error message like this in the Log output. Error: The query requires an index. You can create it here: https://console.firebase.google.com/v1/r/project/my-google-cloud-project/firestore/indexes?create_composite=xyzHold CMD / CTRL and click the link to open it in the browser. Creating the index takes a few minutes, even for empty collections. Click Run again to see your results once the index is ready or to check whether it's ready yet.

Order-by Clauses

Results are sorted by their document id by default. When using a range (<, <=, >, >=, starts-with) or not equals (!=, not-in) comparison, your first ordering must be on the same field, which is a Firestore limitation. You can still specify the order direction (ascending or descending) though. Firefoo will remind you about this by showing a hint and auto-inserting the order-by line.
When specifying multiple order-by clauses, the order of the condition lines matters! Order clauses that are first have precedence over later ones. Just like with where conditions, you need an index to order by multiple fields.

Path

When opening a collection from the sidebar, the path input field is auto-populated with the correct path to the collection. Modify this path to request another collection from the same tab.
It's also possible to query subcollections by providing the full path to the subcollection in the path field, e.g. myCollection/myDocumentId/mySubCollection. To query one specific document only, provide the full path to that document in the path field, e.g. myCollection/myDocumentId. In that case the where, order-by and limit fields disappear, as they apply to collections and subcollections only.

Limit

Limit the number of Firestore documents to return. Note that Firefoo has no maximum limit, unlike the web and mobile SDKs, which have a maximum limit of 10,000 documents. Set to zero to return all documents, but be careful as this might download millions of documents!

The in and array-contains-any Operators

The in and array-contains-any operators expect a list of at most 10 elements as comparator. In Firefoo, you specify it in JSON syntax. This array may contain all valid primitive JSON types: strings, numbers, booleans and null, e.g.["abc", 42.13, true, null] Nested maps and arrays cannot be part of the specified array.

Searching for Strings

Beware that string equality is case-sensitive! There's no way to query Firestore for case-insensitive input out of the box. You can design your data structure around that by saving an upper-case version of the target string in a field next to it and using an upper-case variant when querying as well.
Firefoo provides an additional starts-with operator in addition to the default Firestore operators. It's a string prefix-search that is converted to one >= and one < string comparison behind the scenes. This operator is case-sensitive as well!
Full-text search (searching for parts of a string) is not supported by Firebase as is, but there are paid extensions that work well with Firestore, see the Firebase Documentation with links to these third-party search providers.

Filter for Time Ranges

When you have a where clause on a native Firestore Timestamp field, your compared value must be of the Time type. Comparing to numbers (like unix timestamps) or string representation of date-times do not work. To filter for a time range, use two where conditions:
  1. field >= start time
  2. field <= end time

Firestore Query Limitations

To achieve effortless scaling, there are limitations on which filter combinations are possible. These design decisions are at the core of Firebase Firestore, so that Firefoo cannot work around them.
  • Range (<, <=, >, >=, starts-with) or not equals (!=, not-in) comparisons must all filter on the same field.
  • You can use at most one array-contains clause per query.
  • You can't combine array-contains with array-contains-any.
  • You can use at most one in, not-in, or array-contains-any clause per query.
  • You can't order your query by a field included in an equality (==) or in clause.
Firefoo shows a warning when your query breaks these rules even before executing. Read more about these limitations on the Firebase documentation for queries and orders.

Query Costs

There is no hidden cost in running Firebase queries through Firefoo. Every document in the result set counts as one read operation.