Paginate data with query cursors

With query cursors in Cloud Firestore, you can split data returned by a query 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 the where() method described in Simple Queries.

Add a simple cursor to a query

Use the startAt() or startAfter() methods to define the start point for a query. The startAt() method includes the start point, while the startAfter() method excludes it.

For example, if you use startAt(A) in a query, it returns the entire alphabet. If you use startAfter(A) instead, it returns B-Z.

Web

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

Web

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 a Cloud Firestore client, refer to Cloud 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 the endAt() or endBefore() methods to define an end point for your query results.

Web

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

Web

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 a Cloud Firestore client, refer to Cloud 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 end point of the query cursor. The values in the document snapshot serve as the values in the query cursor.

For example, take a snapshot of a "San Francisco" document in your data set of cities and populations. Then, use that document snapshot as the start point for your population query cursor. Your query will return all the cities with a population larger than or equal to San Francisco's, as defined in the document 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

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 a Cloud Firestore client, refer to Cloud 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 the limit() method. For example, use the last document in a batch as the start of a cursor for the next 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

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 a Cloud Firestore client, refer to Cloud 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 can make the cursor position more precise by adding additional fields. This is particularly useful if your data set includes multiple documents that all have the 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 start or end point and reduce ambiguity.

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

Cities
NameState
SpringfieldMassachusetts
SpringfieldMissouri
SpringfieldWisconsin

To start at a specific Springfield, you could add the state as a secondary condition 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

// 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 a Cloud Firestore client, refer to Cloud 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"])