Paginate data with query cursors

With query cursors inCloud Firestore, you can split data returned by aquery into batches according to the parameters you define in your query.

Query cursors define the start and end points for a query, allowing you to:

  • Return a subset of the data.
  • Paginate query results.

However, to define a specific range for a query, you should use thewhere()method described inSimple Queries.

Add a simple cursor to a query

Use thestartAt() orstartAfter() methods to define the start point for a query.ThestartAt() method includes the start point, while thestartAfter() methodexcludes it.

For example, if you usestartAt(A) in a query, it returns the entire alphabet.If you usestartAfter(A) instead, it returnsB-Z.

Web

import{query,orderBy,startAt}from"firebase/firestore";constq=query(citiesRef,orderBy("population"),startAt(1000000));

Web

Learn more about the tree-shakeable modular Web API and its advantages over the namespaced API.
citiesRef.orderBy("population").startAt(1000000);
Swift
Note: This product is not available on watchOS and App Clip targets.
// Get all cities with population over one million, ordered by population.db.collection("cities").order(by:"population").start(at:[1000000])
Objective-C
Note: This product is not available on watchOS and App Clip targets.
// Get all cities with population over one million, ordered by population.[[[dbcollectionWithPath:@"cities"]queryOrderedByField:@"population"]queryStartingAtValues:@[@1000000]];

Kotlin

// Get all cities with a population >= 1,000,000, ordered by population,db.collection("cities").orderBy("population").startAt(1000000)

Java

// Get all cities with a population >= 1,000,000, ordered by population,db.collection("cities").orderBy("population").startAt(1000000);

Dart

db.collection("cities").orderBy("population").startAt([1000000]);
Java
Queryquery=cities.orderBy("population").startAt(4921000L);
Python
cities_ref=db.collection("cities")query_start_at=cities_ref.order_by("population").start_at({"population":1000000})

Python

cities_ref=db.collection("cities")query_start_at=cities_ref.order_by("population").start_at({"population":1000000})
C++
// Get all cities with a population >= 1,000,000, ordered by population,db->Collection("cities").OrderBy("population").StartAt({FieldValue::Integer(1000000)});
Node.js
conststartAtRes=awaitdb.collection('cities').orderBy('population').startAt(1000000).get();
Go
query:=client.Collection("cities").OrderBy("population",firestore.Asc).StartAt(1000000)
PHP

PHP

For more on installing and creating aCloud Firestore client, refer toCloud Firestore Client Libraries.

$query = $citiesRef    ->orderBy('population')    ->startAt([1000000]);
Unity
Queryquery=citiesRef.OrderBy("Population").StartAt(1000000);
C#
Queryquery=citiesRef.OrderBy("Population").StartAt(1000000);
Ruby
query=cities_ref.order("population").start_at(1_000_000)

Similarly, use theendAt() orendBefore() methods to define an end pointfor your query results.

Web

import{query,orderBy,endAt}from"firebase/firestore";constq=query(citiesRef,orderBy("population"),endAt(1000000));

Web

Learn more about the tree-shakeable modular Web API and its advantages over the namespaced API.
citiesRef.orderBy("population").endAt(1000000);
Swift
Note: This product is not available on watchOS and App Clip targets.
// Get all cities with population less than one million, ordered by population.db.collection("cities").order(by:"population").end(at:[1000000])
Objective-C
Note: This product is not available on watchOS and App Clip targets.
// Get all cities with population less than one million, ordered by population.[[[dbcollectionWithPath:@"cities"]queryOrderedByField:@"population"]queryEndingAtValues:@[@1000000]];

Kotlin

// Get all cities with a population <= 1,000,000, ordered by population,db.collection("cities").orderBy("population").endAt(1000000)

Java

// Get all cities with a population <= 1,000,000, ordered by population,db.collection("cities").orderBy("population").endAt(1000000);

Dart

db.collection("cities").orderBy("population").endAt([1000000]);
Java
Queryquery=cities.orderBy("population").endAt(4921000L);
Python
cities_ref=db.collection("cities")query_end_at=cities_ref.order_by("population").end_at({"population":1000000})

Python

cities_ref=db.collection("cities")query_end_at=cities_ref.order_by("population").end_at({"population":1000000})
C++
// Get all cities with a population <= 1,000,000, ordered by population,db->Collection("cities").OrderBy("population").EndAt({FieldValue::Integer(1000000)});
Node.js
constendAtRes=awaitdb.collection('cities').orderBy('population').endAt(1000000).get();
Go
query:=client.Collection("cities").OrderBy("population",firestore.Asc).EndAt(1000000)
PHP

PHP

For more on installing and creating aCloud Firestore client, refer toCloud Firestore Client Libraries.

$query = $citiesRef    ->orderBy('population')    ->endAt([1000000]);
Unity
Queryquery=citiesRef.OrderBy("Population").EndAt(1000000);
C#
Queryquery=citiesRef.OrderBy("Population").EndAt(1000000);
Ruby
query=cities_ref.order("population").end_at(1_000_000)

Use a document snapshot to define the query cursor

You can also pass a document snapshot to the cursor clause as the start or endpoint of the query cursor. The values in the document snapshot serve as thevalues in the query cursor.

For example, take a snapshot of a "San Francisco" document in your dataset of cities and populations. Then, use that document snapshot as the startpoint for your population query cursor. Your query will return all the citieswith a population larger than or equal to San Francisco's, as defined in thedocument snapshot.

Web

import{collection,doc,getDoc,query,orderBy,startAt}from"firebase/firestore";constcitiesRef=collection(db,"cities");constdocSnap=awaitgetDoc(doc(citiesRef,"SF"));// Get all cities with a population bigger than San FranciscoconstbiggerThanSf=query(citiesRef,orderBy("population"),startAt(docSnap));// ...

Web

Learn more about the tree-shakeable modular Web API and its advantages over the namespaced API.
varcitiesRef=db.collection("cities");returncitiesRef.doc("SF").get().then((doc)=>{// Get all cities with a population bigger than San FranciscovarbiggerThanSf=citiesRef.orderBy("population").startAt(doc);// ...});
Swift
Note: This product is not available on watchOS and App Clip targets.
db.collection("cities").document("SF").addSnapshotListener{(document,error)inguardletdocument=documentelse{print("Error retreving cities:\(error.debugDescription)")return}// Get all cities with a population greater than or equal to San Francisco.letsfSizeOrBigger=db.collection("cities").order(by:"population").start(atDocument:document)}
Objective-C
Note: This product is not available on watchOS and App Clip targets.
[[[dbcollectionWithPath:@"cities"]documentWithPath:@"SF"]addSnapshotListener:^(FIRDocumentSnapshot*snapshot,NSError*error){if(snapshot==nil){NSLog(@"Error retreiving cities: %@",error);return;}// Get all cities with a population greater than or equal to San Francisco.FIRQuery*sfSizeOrBigger=[[[dbcollectionWithPath:@"cities"]queryOrderedByField:@"population"]queryStartingAtDocument:snapshot];}];

Kotlin

// Get the data for "San Francisco"db.collection("cities").document("SF").get().addOnSuccessListener{documentSnapshot->// Get all cities with a population bigger than San Francisco.valbiggerThanSf=db.collection("cities").orderBy("population").startAt(documentSnapshot)// ...}

Java

// Get the data for "San Francisco"db.collection("cities").document("SF").get().addOnSuccessListener(newOnSuccessListener<DocumentSnapshot>(){@OverridepublicvoidonSuccess(DocumentSnapshotdocumentSnapshot){// Get all cities with a population bigger than San Francisco.QuerybiggerThanSf=db.collection("cities").orderBy("population").startAt(documentSnapshot);// ...}});

Dart

db.collection("cities").doc("SF").get().then((documentSnapshot){finalbiggerThanSf=db.collection("cities").orderBy("population").startAtDocument(documentSnapshot);},onError:(e)=>print("Error:$e"),);
Java
// Fetch the snapshot with an API call, waiting for a maximum of 30 seconds for a result.ApiFuture<DocumentSnapshot>future=db.collection("cities").document("SF").get();DocumentSnapshotsnapshot=future.get(30,TimeUnit.SECONDS);// Construct the queryQueryquery=db.collection("cities").orderBy("population").startAt(snapshot);
Python
doc_ref=db.collection("cities").document("SF")snapshot=doc_ref.get()start_at_snapshot=(db.collection("cities").order_by("population").start_at(snapshot))

Python

doc_ref=db.collection("cities").document("SF")snapshot=awaitdoc_ref.get()start_at_snapshot=(db.collection("cities").order_by("population").start_at(snapshot))
C++
db->Collection("cities").Document("SF").Get().OnCompletion([db](constFuture<DocumentSnapshot>&future){if(future.error()==Error::kErrorOk){constDocumentSnapshot&document_snapshot=*future.result();Querybigger_than_sf=db->Collection("cities").OrderBy("population").StartAt({document_snapshot});// ...}});
Node.js
constdocRef=db.collection('cities').doc('SF');constsnapshot=awaitdocRef.get();conststartAtSnapshot=db.collection('cities').orderBy('population').startAt(snapshot);awaitstartAtSnapshot.limit(10).get();
Go
cities:=client.Collection("cities")dsnap,err:=cities.Doc("SF").Get(ctx)iferr!=nil{fmt.Println(err)}query:=cities.OrderBy("population",firestore.Asc).StartAt(dsnap.Data()["population"]).Documents(ctx)
PHP

PHP

For more on installing and creating aCloud Firestore client, refer toCloud Firestore Client Libraries.

$citiesRef = $db->collection('samples/php/cities');$docRef = $citiesRef->document('SF');$snapshot = $docRef->snapshot();$query = $citiesRef    ->orderBy('population')    ->startAt($snapshot);
Unity
CollectionReferencecitiesRef=db.Collection("cities");DocumentReferencedocRef=citiesRef.Document("SF");docRef.GetSnapshotAsync().ContinueWith((snapshotTask)=>{Queryquery=citiesRef.OrderBy("Population").StartAt(snapshotTask.Result);});
C#
CollectionReferencecitiesRef=db.Collection("cities");DocumentReferencedocRef=citiesRef.Document("SF");DocumentSnapshotsnapshot=awaitdocRef.GetSnapshotAsync();Queryquery=citiesRef.OrderBy("Population").StartAt(snapshot);
Ruby
doc_ref=firestore.doc"#{collection_path}/SF"snapshot=doc_ref.getquery=cities_ref.order("population").start_at(snapshot)

Paginate a query

Paginate queries by combining query cursors with thelimit() method.For example, use the last document in a batch as the start of a cursor for thenext batch.

Web

import{collection,query,orderBy,startAfter,limit,getDocs}from"firebase/firestore";// Query the first page of docsconstfirst=query(collection(db,"cities"),orderBy("population"),limit(25));constdocumentSnapshots=awaitgetDocs(first);// Get the last visible documentconstlastVisible=documentSnapshots.docs[documentSnapshots.docs.length-1];console.log("last",lastVisible);// Construct a new query starting at this document,// get the next 25 cities.constnext=query(collection(db,"cities"),orderBy("population"),startAfter(lastVisible),limit(25));

Web

Learn more about the tree-shakeable modular Web API and its advantages over the namespaced API.
varfirst=db.collection("cities").orderBy("population").limit(25);returnfirst.get().then((documentSnapshots)=>{// Get the last visible documentvarlastVisible=documentSnapshots.docs[documentSnapshots.docs.length-1];console.log("last",lastVisible);// Construct a new query starting at this document,// get the next 25 cities.varnext=db.collection("cities").orderBy("population").startAfter(lastVisible).limit(25);});
Swift
Note: This product is not available on watchOS and App Clip targets.
// Construct query for first 25 cities, ordered by populationletfirst=db.collection("cities").order(by:"population").limit(to:25)first.addSnapshotListener{(snapshot,error)inguardletsnapshot=snapshotelse{print("Error retreving cities:\(error.debugDescription)")return}guardletlastSnapshot=snapshot.documents.lastelse{// The collection is empty.return}// Construct a new query starting after this document,// retrieving the next 25 cities.letnext=db.collection("cities").order(by:"population").start(afterDocument:lastSnapshot)// Use the query for pagination.// ...}
Objective-C
Note: This product is not available on watchOS and App Clip targets.
FIRQuery*first=[[[dbcollectionWithPath:@"cities"]queryOrderedByField:@"population"]queryLimitedTo:25];[firstaddSnapshotListener:^(FIRQuerySnapshot*snapshot,NSError*error){if(snapshot==nil){NSLog(@"Error retreiving cities: %@",error);return;}if(snapshot.documents.count==0){return;}FIRDocumentSnapshot*lastSnapshot=snapshot.documents.lastObject;// Construct a new query starting after this document,// retreiving the next 25 cities.FIRQuery*next=[[[dbcollectionWithPath:@"cities"]queryOrderedByField:@"population"]queryStartingAfterDocument:lastSnapshot];// Use the query for pagination.// ...}];

Kotlin

// Construct query for first 25 cities, ordered by populationvalfirst=db.collection("cities").orderBy("population").limit(25)first.get().addOnSuccessListener{documentSnapshots->// ...// Get the last visible documentvallastVisible=documentSnapshots.documents[documentSnapshots.size()-1]// Construct a new query starting at this document,// get the next 25 cities.valnext=db.collection("cities").orderBy("population").startAfter(lastVisible).limit(25)// Use the query for pagination// ...}

Java

// Construct query for first 25 cities, ordered by populationQueryfirst=db.collection("cities").orderBy("population").limit(25);first.get().addOnSuccessListener(newOnSuccessListener<QuerySnapshot>(){@OverridepublicvoidonSuccess(QuerySnapshotdocumentSnapshots){// ...// Get the last visible documentDocumentSnapshotlastVisible=documentSnapshots.getDocuments().get(documentSnapshots.size()-1);// Construct a new query starting at this document,// get the next 25 cities.Querynext=db.collection("cities").orderBy("population").startAfter(lastVisible).limit(25);// Use the query for pagination// ...}});

Dart

// Construct query for first 25 cities, ordered by populationfinalfirst=db.collection("cities").orderBy("population").limit(25);first.get().then((documentSnapshots){// Get the last visible documentfinallastVisible=documentSnapshots.docs[documentSnapshots.size-1];// Construct a new query starting at this document,// get the next 25 cities.finalnext=db.collection("cities").orderBy("population").startAfterDocument(lastVisible).limit(25);// Use the query for pagination// ...},onError:(e)=>print("Error completing:$e"),);
Java
// Construct query for first 25 cities, ordered by population.CollectionReferencecities=db.collection("cities");QueryfirstPage=cities.orderBy("population").limit(25);// Wait for the results of the API call, waiting for a maximum of 30 seconds for a result.ApiFuture<QuerySnapshot>future=firstPage.get();List<QueryDocumentSnapshot>docs=future.get(30,TimeUnit.SECONDS).getDocuments();// Construct query for the next 25 cities.QueryDocumentSnapshotlastDoc=docs.get(docs.size()-1);QuerysecondPage=cities.orderBy("population").startAfter(lastDoc).limit(25);future=secondPage.get();docs=future.get(30,TimeUnit.SECONDS).getDocuments();
Python
cities_ref=db.collection("cities")first_query=cities_ref.order_by("population").limit(3)# Get the last document from the resultsdocs=first_query.stream()last_doc=list(docs)[-1]# Construct a new query starting at this document# Note: this will not have the desired effect if# multiple cities have the exact same population valuelast_pop=last_doc.to_dict()["population"]next_query=(cities_ref.order_by("population").start_after({"population":last_pop}).limit(3))# Use the query for pagination# ...

Python

cities_ref=db.collection("cities")first_query=cities_ref.order_by("population").limit(3)# Get the last document from the resultsdocs=[dasyncfordinfirst_query.stream()]last_doc=list(docs)[-1]# Construct a new query starting at this document# Note: this will not have the desired effect if# multiple cities have the exact same population valuelast_pop=last_doc.to_dict()["population"]next_query=(cities_ref.order_by("population").start_after({"population":last_pop}).limit(3))# Use the query for pagination# ...
C++
// Construct query for first 25 cities, ordered by populationQueryfirst=db->Collection("cities").OrderBy("population").Limit(25);first.Get().OnCompletion([db](constFuture<QuerySnapshot>&future){if(future.error()!=Error::kErrorOk){// Handle error...return;}// Get the last visible documentconstQuerySnapshot&document_snapshots=*future.result();std::vector<DocumentSnapshot>documents=document_snapshots.documents();constDocumentSnapshot&last_visible=documents.back();// Construct a new query starting at this document,// get the next 25 cities.Querynext=db->Collection("cities").OrderBy("population").StartAfter(last_visible).Limit(25);// Use the query for pagination// ...});
Node.js
constfirst=db.collection('cities').orderBy('population').limit(3);constsnapshot=awaitfirst.get();// Get the last documentconstlast=snapshot.docs[snapshot.docs.length-1];// Construct a new query starting at this document.// Note: this will not have the desired effect if multiple// cities have the exact same population value.constnext=db.collection('cities').orderBy('population').startAfter(last.data().population).limit(3);// Use the query for pagination// ...
Go
cities:=client.Collection("cities")// Get the first 25 cities, ordered by population.firstPage:=cities.OrderBy("population",firestore.Asc).Limit(25).Documents(ctx)docs,err:=firstPage.GetAll()iferr!=nil{returnerr}// Get the last document.lastDoc:=docs[len(docs)-1]// Construct a new query to get the next 25 cities.secondPage:=cities.OrderBy("population",firestore.Asc).StartAfter(lastDoc.Data()["population"]).Limit(25)// ...
PHP

PHP

For more on installing and creating aCloud Firestore client, refer toCloud Firestore Client Libraries.

$citiesRef = $db->collection('samples/php/cities');$firstQuery = $citiesRef->orderBy('population')->limit(3);# Get the last document from the results$documents = $firstQuery->documents();$lastPopulation = 0;foreach ($documents as $document) {    $lastPopulation = $document['population'];}# Construct a new query starting at this document# Note: this will not have the desired effect if multiple cities have the exact same population value$nextQuery = $citiesRef->orderBy('population')->startAfter([$lastPopulation]);$snapshot = $nextQuery->documents();
Unity
CollectionReferencecitiesRef=db.Collection("cities");QueryfirstQuery=citiesRef.OrderBy("Population").Limit(3);// Get the last document from the resultsfirstQuery.GetSnapshotAsync().ContinueWith((querySnapshotTask)=>{longlastPopulation=0;foreach(DocumentSnapshotdocumentSnapshotinquerySnapshotTask.Result.Documents){lastPopulation=documentSnapshot.GetValue<long>("Population");}// Construct a new query starting at this document.// Note: this will not have the desired effect if multiple cities have the exact same population valueQuerysecondQuery=citiesRef.OrderBy("Population").StartAfter(lastPopulation);Task<QuerySnapshot>secondQuerySnapshot=secondQuery.GetSnapshotAsync();
C#
CollectionReferencecitiesRef=db.Collection("cities");QueryfirstQuery=citiesRef.OrderBy("Population").Limit(3);// Get the last document from the resultsQuerySnapshotquerySnapshot=awaitfirstQuery.GetSnapshotAsync();longlastPopulation=0;foreach(DocumentSnapshotdocumentSnapshotinquerySnapshot.Documents){lastPopulation=documentSnapshot.GetValue<long>("Population");}// Construct a new query starting at this document.// Note: this will not have the desired effect if multiple cities have the exact same population valueQuerysecondQuery=citiesRef.OrderBy("Population").StartAfter(lastPopulation);QuerySnapshotsecondQuerySnapshot=awaitsecondQuery.GetSnapshotAsync();
Ruby
cities_ref=firestore.colcollection_pathfirst_query=cities_ref.order("population").limit(3)# Get the last document from the results.last_population=0first_query.getdo|city|last_population=city.data[:population]end# Construct a new query starting at this document.# Note: this will not have the desired effect if multiple cities have the exact same population value.second_query=cities_ref.order("population").start_after(last_population)second_query.getdo|city|puts"Document#{city.document_id} returned by paginated query cursor."end

Set cursor based on multiple fields

When using a cursor based on a field value (not a DocumentSnapshot), you canmake the cursor position more precise by adding additional fields. This isparticularly useful if your data set includes multiple documents that all havethe same value for your cursor field, making the cursor's position ambiguous.You can add additional field values to your cursor to further specify the startor end point and reduce ambiguity.

For example, in a data set containing all the cities named "Springfield" in theUnited States, there would be multiple start points for a query set tostart at "Springfield":

Cities
NameState
SpringfieldMassachusetts
SpringfieldMissouri
SpringfieldWisconsin

To start at a specific Springfield, you could add the state as a secondarycondition in your cursor clause.

Web

// Will return all Springfieldsimport{collection,query,orderBy,startAt}from"firebase/firestore";constq1=query(collection(db,"cities"),orderBy("name"),orderBy("state"),startAt("Springfield"));// Will return "Springfield, Missouri" and "Springfield, Wisconsin"constq2=query(collection(db,"cities"),orderBy("name"),orderBy("state"),startAt("Springfield","Missouri"));

Web

Learn more about the tree-shakeable modular Web API and its advantages over the namespaced API.
// Will return all Springfieldsdb.collection("cities").orderBy("name").orderBy("state").startAt("Springfield");// Will return "Springfield, Missouri" and "Springfield, Wisconsin"db.collection("cities").orderBy("name").orderBy("state").startAt("Springfield","Missouri");
Swift
Note: This product is not available on watchOS and App Clip targets.
// Will return all Springfieldsdb.collection("cities").order(by:"name").order(by:"state").start(at:["Springfield"])// Will return "Springfield, Missouri" and "Springfield, Wisconsin"db.collection("cities").order(by:"name").order(by:"state").start(at:["Springfield","Missouri"])
Objective-C
Note: This product is not available on watchOS and App Clip targets.
// Will return all Springfields[[[[dbcollectionWithPath:@"cities"]queryOrderedByField:@"name"]queryOrderedByField:@"state"]queryStartingAtValues:@[@"Springfield"]];// Will return "Springfield, Missouri" and "Springfield, Wisconsin"[[[[dbcollectionWithPath:@"cities"]queryOrderedByField:@"name"]queryOrderedByField:@"state"]queryStartingAtValues:@[@"Springfield",@"Missouri"]];

Kotlin

// Will return all Springfieldsdb.collection("cities").orderBy("name").orderBy("state").startAt("Springfield")// Will return "Springfield, Missouri" and "Springfield, Wisconsin"db.collection("cities").orderBy("name").orderBy("state").startAt("Springfield","Missouri")

Java

// Will return all Springfieldsdb.collection("cities").orderBy("name").orderBy("state").startAt("Springfield");// Will return "Springfield, Missouri" and "Springfield, Wisconsin"db.collection("cities").orderBy("name").orderBy("state").startAt("Springfield","Missouri");

Dart

// Will return all Springfieldsdb.collection("cities").orderBy("name").orderBy("state").startAt(["Springfield"]);// Will return "Springfield, Missouri" and "Springfield, Wisconsin"db.collection("cities").orderBy("name").orderBy("state").startAt(["Springfield","Missouri"]);
Java
// Will return all SpringfieldsQueryquery1=db.collection("cities").orderBy("name").orderBy("state").startAt("Springfield");// Will return "Springfield, Missouri" and "Springfield, Wisconsin"Queryquery2=db.collection("cities").orderBy("name").orderBy("state").startAt("Springfield","Missouri");
Python
start_at_name=(db.collection("cities").order_by("name").start_at({"name":"Springfield"}))start_at_name_and_state=(db.collection("cities").order_by("name").order_by("state").start_at({"name":"Springfield","state":"Missouri"}))

Python

start_at_name=(db.collection("cities").order_by("name").order_by("state").start_at({"name":"Springfield"}))start_at_name_and_state=(db.collection("cities").order_by("name").order_by("state").start_at({"name":"Springfield","state":"Missouri"}))
C++
// This is not yet supported.
Node.js
// Will return all SpringfieldsconststartAtNameRes=awaitdb.collection('cities').orderBy('name').orderBy('state').startAt('Springfield').get();// Will return 'Springfield, Missouri' and 'Springfield, Wisconsin'conststartAtNameAndStateRes=awaitdb.collection('cities').orderBy('name').orderBy('state').startAt('Springfield','Missouri').get();
Go
// Will return all Springfields.client.Collection("cities").OrderBy("name",firestore.Asc).OrderBy("state",firestore.Asc).StartAt("Springfield")// Will return Springfields where state comes after Wisconsin.client.Collection("cities").OrderBy("name",firestore.Asc).OrderBy("state",firestore.Asc).StartAt("Springfield","Wisconsin")
PHP

PHP

For more on installing and creating aCloud Firestore client, refer toCloud Firestore Client Libraries.

// Will return all Springfields$query1 = $db    ->collection('samples/php/cities')    ->orderBy('name')    ->orderBy('state')    ->startAt(['Springfield']);// Will return "Springfield, Missouri" and "Springfield, Wisconsin"$query2 = $db    ->collection('samples/php/cities')    ->orderBy('name')    ->orderBy('state')    ->startAt(['Springfield', 'Missouri']);
Unity
Queryquery1=db.Collection("cities").OrderBy("Name").OrderBy("State").StartAt("Springfield");Queryquery2=db.Collection("cities").OrderBy("Name").OrderBy("State").StartAt("Springfield","Missouri");
C#
Queryquery1=db.Collection("cities").OrderBy("Name").OrderBy("State").StartAt("Springfield");Queryquery2=db.Collection("cities").OrderBy("Name").OrderBy("State").StartAt("Springfield","Missouri");
Ruby
# Will return all Springfieldsquery1=firestore.col(collection_path).order("name").order("state").start_at("Springfield")# Will return "Springfield, Missouri" and "Springfield, Wisconsin"query2=firestore.col(collection_path).order("name").order("state").start_at(["Springfield","Missouri"])

Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2026-02-18 UTC.