Query

QuerySnapshot, QueryDocumentSnapshot

the query snapshot contains zero or more documents.

Firestore answers to a query with a query snapshot, regardless if there are matches or not. The documents it contains, if any, are wrapped individually as a QueryDocumentSnapshot, which is an API that extends DocumentSnapshot and that is mostly the same. The difference in this scenario is that they are always non-empty.

We check if the query snapshot is empty

if (querySnaptshot.empty) {
    return []
}

The (non-empty) queryDocumentSnapshots, are available at docs as an array. A queryDocumentSnapshot guarantees it contains an actual document, due to the context in which the docs array has been built, with only non-empty snapshots. For simplicity, we may call it a docSnapshot and we use the DocumentSnapshot API.

querySnaptshot.docs

const cats = querySnaptshot.docs.map((docSnapshot) => docSnapshot.data())

Query

Read data

read several documents

  • we provide a Query.
  • We receive a querySnapshot
getDocs(query(..))
collection(..).where(..).orderBy(..).limit(..).get()

note on getting all documents

A bare collection ref is accepted as a query, and we receive all documents. It's rarerly used as it's often better to:

specify some order/sorting criteria

limit the number of documents

getDocs(collectionRef)
collectionRef.get()

Query

we query a specific part of the collection, aka the documents that match a criteria or a set of criteria.

const q = query(collectionRef, where(..), where(..), orderBy(..), limit(..))

const q = collection(..).where(..).orderBy(..).limit(..)

where

filter documents based on a property whose value must follow a rule. It filters out the document who do not have this property.

where(propertyName, operator, value)
where("id", "==", user.id)

operator (provided as string)

<
<=
>
>=
==
!=
array-contains // the property is an array and contains the specified value
array-contains-any // the property is an array and contains at least one of the specified values. contains A or B or C ..
in // the property is equal to at least one of the specified value. is equal to A or B or C

not-in // the property must be different from all the specified values. not A and not B and not C.

orderBy

by default, ascending

sort the fetched document by a criteria

orderBy(propertyName, orderDirection)
orderBy("postCount") // ascending
orderBy("postCount", "asc")
orderBy("postCount", "desc")

limit

get at most n documents

limit(n)
limit(5)

startAt, startAfter

When doing pagingation, we either the store:

the count n of document we already fetched

the snapshot docSnapshot of the document we fetched last

startAt(n)
startAt(docSnapshot)

startAfter(n) // does not include n
startAfter(docSnapshot) // does not include docSnapshot

Run the query

We assume we will receive one or more documents, as such, we use the getDocs function

getDocs(query)
query.get()

Real time listener

we may target

a single document with its reference

several documents through a query

we provide a callback as for what to do with the query snapshot or the document snapshot.

query real time read

v9

const unsub = onSnapshot(query, (qs) => {
    const documents = qs.docs.map((docSnapshot) => docSnapshot.data())
    setMessages(documents)
})

document real time read

const unsub = onSnapshot(docRef, (docSnapshot) => {
    console.log("Current data: ", docSnapshot.data())
})
earlymorning logo

© 2025 - All rights reserved

Query

QuerySnapshot, QueryDocumentSnapshot

the query snapshot contains zero or more documents.

Firestore answers to a query with a query snapshot, regardless if there are matches or not. The documents it contains, if any, are wrapped individually as a QueryDocumentSnapshot, which is an API that extends DocumentSnapshot and that is mostly the same. The difference in this scenario is that they are always non-empty.

We check if the query snapshot is empty

if (querySnaptshot.empty) {
    return []
}

The (non-empty) queryDocumentSnapshots, are available at docs as an array. A queryDocumentSnapshot guarantees it contains an actual document, due to the context in which the docs array has been built, with only non-empty snapshots. For simplicity, we may call it a docSnapshot and we use the DocumentSnapshot API.

querySnaptshot.docs

const cats = querySnaptshot.docs.map((docSnapshot) => docSnapshot.data())

Query

Read data

read several documents

  • we provide a Query.
  • We receive a querySnapshot
getDocs(query(..))
collection(..).where(..).orderBy(..).limit(..).get()

note on getting all documents

A bare collection ref is accepted as a query, and we receive all documents. It's rarerly used as it's often better to:

specify some order/sorting criteria

limit the number of documents

getDocs(collectionRef)
collectionRef.get()

Query

we query a specific part of the collection, aka the documents that match a criteria or a set of criteria.

const q = query(collectionRef, where(..), where(..), orderBy(..), limit(..))

const q = collection(..).where(..).orderBy(..).limit(..)

where

filter documents based on a property whose value must follow a rule. It filters out the document who do not have this property.

where(propertyName, operator, value)
where("id", "==", user.id)

operator (provided as string)

<
<=
>
>=
==
!=
array-contains // the property is an array and contains the specified value
array-contains-any // the property is an array and contains at least one of the specified values. contains A or B or C ..
in // the property is equal to at least one of the specified value. is equal to A or B or C

not-in // the property must be different from all the specified values. not A and not B and not C.

orderBy

by default, ascending

sort the fetched document by a criteria

orderBy(propertyName, orderDirection)
orderBy("postCount") // ascending
orderBy("postCount", "asc")
orderBy("postCount", "desc")

limit

get at most n documents

limit(n)
limit(5)

startAt, startAfter

When doing pagingation, we either the store:

the count n of document we already fetched

the snapshot docSnapshot of the document we fetched last

startAt(n)
startAt(docSnapshot)

startAfter(n) // does not include n
startAfter(docSnapshot) // does not include docSnapshot

Run the query

We assume we will receive one or more documents, as such, we use the getDocs function

getDocs(query)
query.get()

Real time listener

we may target

a single document with its reference

several documents through a query

we provide a callback as for what to do with the query snapshot or the document snapshot.

query real time read

v9

const unsub = onSnapshot(query, (qs) => {
    const documents = qs.docs.map((docSnapshot) => docSnapshot.data())
    setMessages(documents)
})

document real time read

const unsub = onSnapshot(docRef, (docSnapshot) => {
    console.log("Current data: ", docSnapshot.data())
})