Cloud Firestore provides powerful query functionality for specifying which
documents you want to retrieve from a collection or collection group. These
queries can also be used with either get()
or addSnapshotListener()
, as
described in Get Data and Get Realtime Updates.
Example data
To get started, write some data about cities so we can look at different ways to read it back:
Web v8
var citiesRef = db.collection("cities"); citiesRef.doc("SF").set({ name: "San Francisco", state: "CA", country: "USA", capital: false, population: 860000, regions: ["west_coast", "norcal"] }); citiesRef.doc("LA").set({ name: "Los Angeles", state: "CA", country: "USA", capital: false, population: 3900000, regions: ["west_coast", "socal"] }); citiesRef.doc("DC").set({ name: "Washington, D.C.", state: null, country: "USA", capital: true, population: 680000, regions: ["east_coast"] }); citiesRef.doc("TOK").set({ name: "Tokyo", state: null, country: "Japan", capital: true, population: 9000000, regions: ["kanto", "honshu"] }); citiesRef.doc("BJ").set({ name: "Beijing", state: null, country: "China", capital: true, population: 21500000, regions: ["jingjinji", "hebei"] });
Web v9
import { collection, doc, setDoc } from "firebase/firestore"; const citiesRef = collection(db, "cities"); await setDoc(doc(citiesRef, "SF"), { name: "San Francisco", state: "CA", country: "USA", capital: false, population: 860000, regions: ["west_coast", "norcal"] }); await setDoc(doc(citiesRef, "LA"), { name: "Los Angeles", state: "CA", country: "USA", capital: false, population: 3900000, regions: ["west_coast", "socal"] }); await setDoc(doc(citiesRef, "DC"), { name: "Washington, D.C.", state: null, country: "USA", capital: true, population: 680000, regions: ["east_coast"] }); await setDoc(doc(citiesRef, "TOK"), { name: "Tokyo", state: null, country: "Japan", capital: true, population: 9000000, regions: ["kanto", "honshu"] }); await setDoc(doc(citiesRef, "BJ"), { name: "Beijing", state: null, country: "China", capital: true, population: 21500000, regions: ["jingjinji", "hebei"] });
Swift
let citiesRef = db.collection("cities") citiesRef.document("SF").setData([ "name": "San Francisco", "state": "CA", "country": "USA", "capital": false, "population": 860000, "regions": ["west_coast", "norcal"] ]) citiesRef.document("LA").setData([ "name": "Los Angeles", "state": "CA", "country": "USA", "capital": false, "population": 3900000, "regions": ["west_coast", "socal"] ]) citiesRef.document("DC").setData([ "name": "Washington D.C.", "country": "USA", "capital": true, "population": 680000, "regions": ["east_coast"] ]) citiesRef.document("TOK").setData([ "name": "Tokyo", "country": "Japan", "capital": true, "population": 9000000, "regions": ["kanto", "honshu"] ]) citiesRef.document("BJ").setData([ "name": "Beijing", "country": "China", "capital": true, "population": 21500000, "regions": ["jingjinji", "hebei"] ])
Objective-C
FIRCollectionReference *citiesRef = [self.db collectionWithPath:@"cities"]; [[citiesRef documentWithPath:@"SF"] setData:@{ @"name": @"San Francisco", @"state": @"CA", @"country": @"USA", @"capital": @(NO), @"population": @860000, @"regions": @[@"west_coast", @"norcal"] }]; [[citiesRef documentWithPath:@"LA"] setData:@{ @"name": @"Los Angeles", @"state": @"CA", @"country": @"USA", @"capital": @(NO), @"population": @3900000, @"regions": @[@"west_coast", @"socal"] }]; [[citiesRef documentWithPath:@"DC"] setData:@{ @"name": @"Washington D.C.", @"country": @"USA", @"capital": @(YES), @"population": @680000, @"regions": @[@"east_coast"] }]; [[citiesRef documentWithPath:@"TOK"] setData:@{ @"name": @"Tokyo", @"country": @"Japan", @"capital": @(YES), @"population": @9000000, @"regions": @[@"kanto", @"honshu"] }]; [[citiesRef documentWithPath:@"BJ"] setData:@{ @"name": @"Beijing", @"country": @"China", @"capital": @(YES), @"population": @21500000, @"regions": @[@"jingjinji", @"hebei"] }];
Java
CollectionReference cities = db.collection("cities"); Map<String, Object> data1 = new HashMap<>(); data1.put("name", "San Francisco"); data1.put("state", "CA"); data1.put("country", "USA"); data1.put("capital", false); data1.put("population", 860000); data1.put("regions", Arrays.asList("west_coast", "norcal")); cities.document("SF").set(data1); Map<String, Object> data2 = new HashMap<>(); data2.put("name", "Los Angeles"); data2.put("state", "CA"); data2.put("country", "USA"); data2.put("capital", false); data2.put("population", 3900000); data2.put("regions", Arrays.asList("west_coast", "socal")); cities.document("LA").set(data2); Map<String, Object> data3 = new HashMap<>(); data3.put("name", "Washington D.C."); data3.put("state", null); data3.put("country", "USA"); data3.put("capital", true); data3.put("population", 680000); data3.put("regions", Arrays.asList("east_coast")); cities.document("DC").set(data3); Map<String, Object> data4 = new HashMap<>(); data4.put("name", "Tokyo"); data4.put("state", null); data4.put("country", "Japan"); data4.put("capital", true); data4.put("population", 9000000); data4.put("regions", Arrays.asList("kanto", "honshu")); cities.document("TOK").set(data4); Map<String, Object> data5 = new HashMap<>(); data5.put("name", "Beijing"); data5.put("state", null); data5.put("country", "China"); data5.put("capital", true); data5.put("population", 21500000); data5.put("regions", Arrays.asList("jingjinji", "hebei")); cities.document("BJ").set(data5);
Kotlin+KTX
val cities = db.collection("cities") val data1 = hashMapOf( "name" to "San Francisco", "state" to "CA", "country" to "USA", "capital" to false, "population" to 860000, "regions" to listOf("west_coast", "norcal") ) cities.document("SF").set(data1) val data2 = hashMapOf( "name" to "Los Angeles", "state" to "CA", "country" to "USA", "capital" to false, "population" to 3900000, "regions" to listOf("west_coast", "socal") ) cities.document("LA").set(data2) val data3 = hashMapOf( "name" to "Washington D.C.", "state" to null, "country" to "USA", "capital" to true, "population" to 680000, "regions" to listOf("east_coast") ) cities.document("DC").set(data3) val data4 = hashMapOf( "name" to "Tokyo", "state" to null, "country" to "Japan", "capital" to true, "population" to 9000000, "regions" to listOf("kanto", "honshu") ) cities.document("TOK").set(data4) val data5 = hashMapOf( "name" to "Beijing", "state" to null, "country" to "China", "capital" to true, "population" to 21500000, "regions" to listOf("jingjinji", "hebei") ) cities.document("BJ").set(data5)
Java
CollectionReference cities = db.collection("cities"); List<ApiFuture<WriteResult>> futures = new ArrayList<>(); futures.add( cities .document("SF") .set( new City( "San Francisco", "CA", "USA", false, 860000L, Arrays.asList("west_coast", "norcal")))); futures.add( cities .document("LA") .set( new City( "Los Angeles", "CA", "USA", false, 3900000L, Arrays.asList("west_coast", "socal")))); futures.add( cities .document("DC") .set( new City( "Washington D.C.", null, "USA", true, 680000L, Arrays.asList("east_coast")))); futures.add( cities .document("TOK") .set( new City( "Tokyo", null, "Japan", true, 9000000L, Arrays.asList("kanto", "honshu")))); futures.add( cities .document("BJ") .set( new City( "Beijing", null, "China", true, 21500000L, Arrays.asList("jingjinji", "hebei")))); // (optional) block on documents successfully added ApiFutures.allAsList(futures).get();
Python
class City(object): def __init__(self, name, state, country, capital=False, population=0, regions=[]): self.name = name self.state = state self.country = country self.capital = capital self.population = population self.regions = regions @staticmethod def from_dict(source): # ... def to_dict(self): # ... def __repr__(self): return( f'City(\ name={self.name}, \ country={self.country}, \ population={self.population}, \ capital={self.capital}, \ regions={self.regions}\ )' )cities_ref = db.collection(u'cities') cities_ref.document(u'BJ').set( City(u'Beijing', None, u'China', True, 21500000, [u'hebei']).to_dict()) cities_ref.document(u'SF').set( City(u'San Francisco', u'CA', u'USA', False, 860000, [u'west_coast', u'norcal']).to_dict()) cities_ref.document(u'LA').set( City(u'Los Angeles', u'CA', u'USA', False, 3900000, [u'west_coast', u'socal']).to_dict()) cities_ref.document(u'DC').set( City(u'Washington D.C.', None, u'USA', True, 680000, [u'east_coast']).to_dict()) cities_ref.document(u'TOK').set( City(u'Tokyo', None, u'Japan', True, 9000000, [u'kanto', u'honshu']).to_dict())
C++
CollectionReference cities = db->Collection("cities"); cities.Document("SF").Set({ {"name", FieldValue::String("San Francisco")}, {"state", FieldValue::String("CA")}, {"country", FieldValue::String("USA")}, {"capital", FieldValue::Boolean(false)}, {"population", FieldValue::Integer(860000)}, {"regions", FieldValue::Array({FieldValue::String("west_coast"), FieldValue::String("norcal")})}, }); cities.Document("LA").Set({ {"name", FieldValue::String("Los Angeles")}, {"state", FieldValue::String("CA")}, {"country", FieldValue::String("USA")}, {"capital", FieldValue::Boolean(false)}, {"population", FieldValue::Integer(3900000)}, {"regions", FieldValue::Array({FieldValue::String("west_coast"), FieldValue::String("socal")})}, }); cities.Document("DC").Set({ {"name", FieldValue::String("Washington D.C.")}, {"state", FieldValue::Null()}, {"country", FieldValue::String("USA")}, {"capital", FieldValue::Boolean(true)}, {"population", FieldValue::Integer(680000)}, {"regions", FieldValue::Array({FieldValue::String("east_coast")})}, }); cities.Document("TOK").Set({ {"name", FieldValue::String("Tokyo")}, {"state", FieldValue::Null()}, {"country", FieldValue::String("Japan")}, {"capital", FieldValue::Boolean(true)}, {"population", FieldValue::Integer(9000000)}, {"regions", FieldValue::Array({FieldValue::String("kanto"), FieldValue::String("honshu")})}, }); cities.Document("BJ").Set({ {"name", FieldValue::String("Beijing")}, {"state", FieldValue::Null()}, {"country", FieldValue::String("China")}, {"capital", FieldValue::Boolean(true)}, {"population", FieldValue::Integer(21500000)}, {"regions", FieldValue::Array({FieldValue::String("jingjinji"), FieldValue::String("hebei")})}, });
Node.js
const citiesRef = db.collection('cities'); await citiesRef.doc('SF').set({ name: 'San Francisco', state: 'CA', country: 'USA', capital: false, population: 860000, regions: ['west_coast', 'norcal'] }); await citiesRef.doc('LA').set({ name: 'Los Angeles', state: 'CA', country: 'USA', capital: false, population: 3900000, regions: ['west_coast', 'socal'] }); await citiesRef.doc('DC').set({ name: 'Washington, D.C.', state: null, country: 'USA', capital: true, population: 680000, regions: ['east_coast'] }); await citiesRef.doc('TOK').set({ name: 'Tokyo', state: null, country: 'Japan', capital: true, population: 9000000, regions: ['kanto', 'honshu'] }); await citiesRef.doc('BJ').set({ name: 'Beijing', state: null, country: 'China', capital: true, population: 21500000, regions: ['jingjinji', 'hebei'] });
Go
cities := []struct { id string c City }{ { id: "SF", c: City{Name: "San Francisco", State: "CA", Country: "USA", Capital: false, Population: 860000, Regions: []string{"west_coast", "norcal"}}, }, { id: "LA", c: City{Name: "Los Angeles", State: "CA", Country: "USA", Capital: false, Population: 3900000, Regions: []string{"west_coast", "socal"}}, }, { id: "DC", c: City{Name: "Washington D.C.", Country: "USA", Capital: false, Population: 680000, Regions: []string{"east_coast"}}, }, { id: "TOK", c: City{Name: "Tokyo", Country: "Japan", Capital: true, Population: 9000000, Regions: []string{"kanto", "honshu"}}, }, { id: "BJ", c: City{Name: "Beijing", Country: "China", Capital: true, Population: 21500000, Regions: []string{"jingjinji", "hebei"}}, }, } for _, c := range cities { if _, err := client.Collection("cities").Doc(c.id).Set(ctx, c.c); err != nil { return err } }
PHP
$citiesRef = $db->collection('cities'); $citiesRef->document('SF')->set([ 'name' => 'San Francisco', 'state' => 'CA', 'country' => 'USA', 'capital' => false, 'population' => 860000, 'regions' => ['west_coast', 'norcal'] ]); $citiesRef->document('LA')->set([ 'name' => 'Los Angeles', 'state' => 'CA', 'country' => 'USA', 'capital' => false, 'population' => 3900000, 'regions' => ['west_coast', 'socal'] ]); $citiesRef->document('DC')->set([ 'name' => 'Washington D.C.', 'state' => null, 'country' => 'USA', 'capital' => true, 'population' => 680000, 'regions' => ['east_coast'] ]); $citiesRef->document('TOK')->set([ 'name' => 'Tokyo', 'state' => null, 'country' => 'Japan', 'capital' => true, 'population' => 9000000, 'regions' => ['kanto', 'honshu'] ]); $citiesRef->document('BJ')->set([ 'name' => 'Beijing', 'state' => null, 'country' => 'China', 'capital' => true, 'population' => 21500000, 'regions' => ['jingjinji', 'hebei'] ]); printf('Added example cities data to the cities collection.' . PHP_EOL);
Unity
CollectionReference citiesRef = db.Collection("cities"); citiesRef.Document("SF").SetAsync(new Dictionary<string, object>(){ { "Name", "San Francisco" }, { "State", "CA" }, { "Country", "USA" }, { "Capital", false }, { "Population", 860000 }, { "Regions", new ArrayList{"west_coast", "norcal"} } }); citiesRef.Document("LA").SetAsync(new Dictionary<string, object>(){ { "Name", "Los Angeles" }, { "State", "CA" }, { "Country", "USA" }, { "Capital", false }, { "Population", 3900000 }, { "Regions", new ArrayList{"west_coast", "socal"} } }); citiesRef.Document("DC").SetAsync(new Dictionary<string, object>(){ { "Name", "Washington D.C." }, { "State", null }, { "Country", "USA" }, { "Capital", true }, { "Population", 680000 }, { "Regions", new ArrayList{"east_coast"} } }); citiesRef.Document("TOK").SetAsync(new Dictionary<string, object>(){ { "Name", "Tokyo" }, { "State", null }, { "Country", "Japan" }, { "Capital", true }, { "Population", 9000000 }, { "Regions", new ArrayList{"kanto", "honshu"} } }); citiesRef.Document("BJ").SetAsync(new Dictionary<string, object>(){ { "Name", "Beijing" }, { "State", null }, { "Country", "China" }, { "Capital", true }, { "Population", 21500000 }, { "Regions", new ArrayList{"jingjinji", "hebei"} } });
C#
CollectionReference citiesRef = db.Collection("cities"); await citiesRef.Document("SF").SetAsync(new Dictionary<string, object>(){ { "Name", "San Francisco" }, { "State", "CA" }, { "Country", "USA" }, { "Capital", false }, { "Population", 860000 }, { "Regions", new ArrayList{"west_coast", "norcal"} } }); await citiesRef.Document("LA").SetAsync(new Dictionary<string, object>(){ { "Name", "Los Angeles" }, { "State", "CA" }, { "Country", "USA" }, { "Capital", false }, { "Population", 3900000 }, { "Regions", new ArrayList{"west_coast", "socal"} } }); await citiesRef.Document("DC").SetAsync(new Dictionary<string, object>(){ { "Name", "Washington D.C." }, { "State", null }, { "Country", "USA" }, { "Capital", true }, { "Population", 680000 }, { "Regions", new ArrayList{"east_coast"} } }); await citiesRef.Document("TOK").SetAsync(new Dictionary<string, object>(){ { "Name", "Tokyo" }, { "State", null }, { "Country", "Japan" }, { "Capital", true }, { "Population", 9000000 }, { "Regions", new ArrayList{"kanto", "honshu"} } }); await citiesRef.Document("BJ").SetAsync(new Dictionary<string, object>(){ { "Name", "Beijing" }, { "State", null }, { "Country", "China" }, { "Capital", true }, { "Population", 21500000 }, { "Regions", new ArrayList{"jingjinji", "hebei"} } }); Console.WriteLine("Added example cities data to the cities collection.");
Ruby
cities_ref = firestore.col collection_path cities_ref.doc("SF").set( { name: "San Francisco", state: "CA", country: "USA", capital: false, population: 860_000, regions: ["west_coast", "norcal"] } ) cities_ref.doc("LA").set( { name: "Los Angeles", state: "CA", country: "USA", capital: false, population: 3_900_000, regions: ["west_coast", "socal"] } ) cities_ref.doc("DC").set( { name: "Washington D.C.", state: nil, country: "USA", capital: true, population: 680_000, regions: ["east_coast"] } ) cities_ref.doc("TOK").set( { name: "Tokyo", state: nil, country: "Japan", capital: true, population: 9_000_000, regions: ["kanto", "honshu"] } ) cities_ref.doc("BJ").set( { name: "Beijing", state: nil, country: "China", capital: true, population: 21_500_000, regions: ["jingjinji", "hebei"] } )
Simple queries
The following query returns all cities with state CA
:
Web v8
// Create a reference to the cities collection var citiesRef = db.collection("cities"); // Create a query against the collection. var query = citiesRef.where("state", "==", "CA");
Web v9
// Create a reference to the cities collection import { collection, query, where } from "firebase/firestore"; const citiesRef = collection(db, "cities"); // Create a query against the collection. const q = query(citiesRef, where("state", "==", "CA"));
Swift
// Create a reference to the cities collection let citiesRef = db.collection("cities") // Create a query against the collection. let query = citiesRef.whereField("state", isEqualTo: "CA")
Objective-C
// Create a reference to the cities collection FIRCollectionReference *citiesRef = [self.db collectionWithPath:@"cities"]; // Create a query against the collection. FIRQuery *query = [citiesRef queryWhereField:@"state" isEqualTo:@"CA"];
Java
// Create a reference to the cities collection CollectionReference citiesRef = db.collection("cities"); // Create a query against the collection. Query query = citiesRef.whereEqualTo("state", "CA");
Kotlin+KTX
// Create a reference to the cities collection val citiesRef = db.collection("cities") // Create a query against the collection. val query = citiesRef.whereEqualTo("state", "CA")
Java
// Create a reference to the cities collection CollectionReference cities = db.collection("cities"); // Create a query against the collection. Query query = cities.whereEqualTo("state", "CA"); // retrieve query results asynchronously using query.get() ApiFuture<QuerySnapshot> querySnapshot = query.get(); for (DocumentSnapshot document : querySnapshot.get().getDocuments()) { System.out.println(document.getId()); }
Python
# Create a reference to the cities collection cities_ref = db.collection(u'cities') # Create a query against the collection query_ref = cities_ref.where(u'state', u'==', u'CA')
C++
CollectionReference cities_ref = db->Collection("cities"); // Create a query against the collection. Query query_ca = cities_ref.WhereEqualTo("state", FieldValue::String("CA"));
Node.js
// Create a reference to the cities collection const citiesRef = db.collection('cities'); // Create a query against the collection const queryRef = citiesRef.where('state', '==', 'CA');
Go
query := client.Collection("cities").Where("state", "==", "CA")
PHP
$citiesRef = $db->collection('cities'); $query = $citiesRef->where('state', '=', 'CA'); $snapshot = $query->documents(); foreach ($snapshot as $document) { printf('Document %s returned by query state=CA' . PHP_EOL, $document->id()); }
Unity
CollectionReference citiesRef = db.Collection("cities"); Query query = citiesRef.WhereEqualTo("State", "CA"); query.GetSnapshotAsync().ContinueWithOnMainThread((querySnapshotTask) => { foreach (DocumentSnapshot documentSnapshot in querySnapshotTask.Result.Documents) { Debug.Log(String.Format("Document {0} returned by query State=CA", documentSnapshot.Id)); } });
C#
CollectionReference citiesRef = db.Collection("cities"); Query query = citiesRef.WhereEqualTo("State", "CA"); QuerySnapshot querySnapshot = await query.GetSnapshotAsync(); foreach (DocumentSnapshot documentSnapshot in querySnapshot.Documents) { Console.WriteLine("Document {0} returned by query State=CA", documentSnapshot.Id); }
Ruby
cities_ref = firestore.col collection_path query = cities_ref.where "state", "=", "CA" query.get do |city| puts "Document #{city.document_id} returned by query state=CA." end
The following query returns all the capital cities:
Web v8
var citiesRef = db.collection("cities"); var query = citiesRef.where("capital", "==", true);
Web v9
import { collection, query, where } from "firebase/firestore"; const citiesRef = collection(db, "cities"); const q = query(citiesRef, where("capital", "==", true));
Swift
let capitalCities = db.collection("cities").whereField("capital", isEqualTo: true)
Objective-C
FIRQuery *capitalCities = [[self.db collectionWithPath:@"cities"] queryWhereField:@"capital" isEqualTo:@YES];
Java
Query capitalCities = db.collection("cities").whereEqualTo("capital", true);
Kotlin+KTX
val capitalCities = db.collection("cities").whereEqualTo("capital", true)
Java
// Create a reference to the cities collection CollectionReference cities = db.collection("cities"); // Create a query against the collection. Query query = cities.whereEqualTo("capital", true); // retrieve query results asynchronously using query.get() ApiFuture<QuerySnapshot> querySnapshot = query.get(); for (DocumentSnapshot document : querySnapshot.get().getDocuments()) { System.out.println(document.getId()); }
Python
cities_ref = db.collection(u'cities') query = cities_ref.where(u'capital', u'==', True)
C++
Query capital_cities = db->Collection("cities").WhereEqualTo( "capital", FieldValue::Boolean(true));
Node.js
// Create a reference to the cities collection const citiesRef = db.collection('cities'); // Create a query against the collection const allCapitalsRes = await citiesRef.where('capital', '==', true).get();
Go
query := client.Collection("cities").Where("capital", "==", true)
PHP
$citiesRef = $db->collection('cities'); $query = $citiesRef->where('capital', '=', true); $snapshot = $query->documents(); foreach ($snapshot as $document) { printf('Document %s returned by query capital=true' . PHP_EOL, $document->id()); }
Unity
CollectionReference citiesRef = db.Collection("cities"); Query query = citiesRef.WhereEqualTo("Capital", true); query.GetSnapshotAsync().ContinueWithOnMainThread((querySnapshotTask) => { foreach (DocumentSnapshot documentSnapshot in querySnapshotTask.Result.Documents) { Debug.Log(String.Format("Document {0} returned by query Capital=true", documentSnapshot.Id)); } });
C#
CollectionReference citiesRef = db.Collection("cities"); Query query = citiesRef.WhereEqualTo("Capital", true); QuerySnapshot querySnapshot = await query.GetSnapshotAsync(); foreach (DocumentSnapshot documentSnapshot in querySnapshot.Documents) { Console.WriteLine("Document {0} returned by query Capital=true", documentSnapshot.Id); }
Ruby
cities_ref = firestore.col collection_path query = cities_ref.where "capital", "=", true query.get do |city| puts "Document #{city.document_id} returned by query capital=true." end
Execute a query
After creating a query object, use the get()
function to retrieve the results:
Web v8
db.collection("cities").where("capital", "==", true) .get() .then((querySnapshot) => { querySnapshot.forEach((doc) => { // doc.data() is never undefined for query doc snapshots console.log(doc.id, " => ", doc.data()); }); }) .catch((error) => { console.log("Error getting documents: ", error); });
Web v9
import { collection, query, where, getDocs } from "firebase/firestore"; const q = query(collection(db, "cities"), where("capital", "==", true)); const querySnapshot = await getDocs(q); querySnapshot.forEach((doc) => { // doc.data() is never undefined for query doc snapshots console.log(doc.id, " => ", doc.data()); });
Swift
db.collection("cities").whereField("capital", isEqualTo: true) .getDocuments() { (querySnapshot, err) in if let err = err { print("Error getting documents: \(err)") } else { for document in querySnapshot!.documents { print("\(document.documentID) => \(document.data())") } } }
Objective-C
[[[self.db collectionWithPath:@"cities"] queryWhereField:@"capital" isEqualTo:@(YES)] getDocumentsWithCompletion:^(FIRQuerySnapshot *snapshot, NSError *error) { if (error != nil) { NSLog(@"Error getting documents: %@", error); } else { for (FIRDocumentSnapshot *document in snapshot.documents) { NSLog(@"%@ => %@", document.documentID, document.data); } } }];
Java
db.collection("cities") .whereEqualTo("capital", true) .get() .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() { @Override public void onComplete(@NonNull Task<QuerySnapshot> task) { if (task.isSuccessful()) { for (QueryDocumentSnapshot document : task.getResult()) { Log.d(TAG, document.getId() + " => " + document.getData()); } } else { Log.d(TAG, "Error getting documents: ", task.getException()); } } });
Kotlin+KTX
db.collection("cities") .whereEqualTo("capital", true) .get() .addOnSuccessListener { documents -> for (document in documents) { Log.d(TAG, "${document.id} => ${document.data}") } } .addOnFailureListener { exception -> Log.w(TAG, "Error getting documents: ", exception) }
Java
//asynchronously retrieve multiple documents ApiFuture<QuerySnapshot> future = db.collection("cities").whereEqualTo("capital", true).get(); // future.get() blocks on response List<QueryDocumentSnapshot> documents = future.get().getDocuments(); for (DocumentSnapshot document : documents) { System.out.println(document.getId() + " => " + document.toObject(City.class)); }
Python
# Note: Use of CollectionRef stream() is prefered to get() docs = db.collection(u'cities').where(u'capital', u'==', True).stream() for doc in docs: print(f'{doc.id} => {doc.to_dict()}')
C++
db->Collection("cities") .WhereEqualTo("capital", FieldValue::Boolean(true)) .Get() .OnCompletion([](const Future<QuerySnapshot>& future) { if (future.error() == Error::kErrorOk) { for (const DocumentSnapshot& document : future.result()->documents()) { std::cout << document << '\n'; } } else { std::cout << "Error getting documents: " << future.error_message() << '\n'; } });
Node.js
const citiesRef = db.collection('cities'); const snapshot = await citiesRef.where('capital', '==', true).get(); if (snapshot.empty) { console.log('No matching documents.'); return; } snapshot.forEach(doc => { console.log(doc.id, '=>', doc.data()); });
Go
fmt.Println("All capital cities:") iter := client.Collection("cities").Where("capital", "==", true).Documents(ctx) for { doc, err := iter.Next() if err == iterator.Done { break } if err != nil { return err } fmt.Println(doc.Data()) }
PHP
$citiesRef = $db->collection('cities'); $query = $citiesRef->where('capital', '=', true); $documents = $query->documents(); foreach ($documents as $document) { if ($document->exists()) { printf('Document data for document %s:' . PHP_EOL, $document->id()); print_r($document->data()); printf(PHP_EOL); } else { printf('Document %s does not exist!' . PHP_EOL, $snapshot->id()); } }
Unity
Query capitalQuery = db.Collection("cities").WhereEqualTo("Capital", true); capitalQuery.GetSnapshotAsync().ContinueWithOnMainThread(task => { QuerySnapshot capitalQuerySnapshot = task.Result; foreach (DocumentSnapshot documentSnapshot in capitalQuerySnapshot.Documents) { Debug.Log(String.Format("Document data for {0} document:", documentSnapshot.Id)); Dictionary<string, object> city = documentSnapshot.ToDictionary(); foreach (KeyValuePair<string, object> pair in city) { Debug.Log(String.Format("{0}: {1}", pair.Key, pair.Value)); } // Newline to separate entries Debug.Log(""); }; });
C#
Query capitalQuery = db.Collection("cities").WhereEqualTo("Capital", true); QuerySnapshot capitalQuerySnapshot = await capitalQuery.GetSnapshotAsync(); foreach (DocumentSnapshot documentSnapshot in capitalQuerySnapshot.Documents) { Console.WriteLine("Document data for {0} document:", documentSnapshot.Id); Dictionary<string, object> city = documentSnapshot.ToDictionary(); foreach (KeyValuePair<string, object> pair in city) { Console.WriteLine("{0}: {1}", pair.Key, pair.Value); } Console.WriteLine(""); }
Ruby
cities_ref = firestore.col collection_path query = cities_ref.where "capital", "=", true query.get do |city| puts "#{city.document_id} data: #{city.data}." end
See Get Data for more information on retrieving query results. You can also add a listener to a query to get the current results and listen for future updates.
Query operators
The where()
method takes three parameters: a field to filter on, a comparison
operator, and a value. Cloud Firestore supports the following comparison
operators:
<
less than<=
less than or equal to==
equal to>
greater than>=
greater than or equal to!=
not equal toarray-contains
array-contains-any
in
not-in
For example:
Web v8
citiesRef.where("state", "==", "CA"); citiesRef.where("population", "<", 100000); citiesRef.where("name", ">=", "San Francisco");
Web v9
const q1 = query(citiesRef, where("state", "==", "CA")); const q2 = query(citiesRef, where("population", "<", 100000)); const q3 = query(citiesRef, where("name", ">=", "San Francisco"));
Swift
citiesRef.whereField("state", isEqualTo: "CA") citiesRef.whereField("population", isLessThan: 100000) citiesRef.whereField("name", isGreaterThanOrEqualTo: "San Francisco")
Objective-C
[citiesRef queryWhereField:@"state" isEqualTo:@"CA"]; [citiesRef queryWhereField:@"population" isLessThan:@100000]; [citiesRef queryWhereField:@"name" isGreaterThanOrEqualTo:@"San Francisco"];
Java
citiesRef.whereEqualTo("state", "CA"); citiesRef.whereLessThan("population", 100000); citiesRef.whereGreaterThanOrEqualTo("name", "San Francisco");
Kotlin+KTX
citiesRef.whereEqualTo("state", "CA") citiesRef.whereLessThan("population", 100000) citiesRef.whereGreaterThanOrEqualTo("name", "San Francisco")
Java
Query stateQuery = cities.whereEqualTo("state", "CA"); Query populationQuery = cities.whereLessThan("population", 1000000L); Query nameQuery = cities.whereGreaterThanOrEqualTo("name", "San Francisco");
Python
cities_ref = db.collection(u'cities') cities_ref.where(u'state', u'==', u'CA') cities_ref.where(u'population', u'<', 1000000) cities_ref.where(u'name', u'>=', u'San Francisco')
C++
cities_ref.WhereEqualTo("state", FieldValue::String("CA")); cities_ref.WhereLessThan("population", FieldValue::Integer(100000)); cities_ref.WhereGreaterThanOrEqualTo("name", FieldValue::String("San Francisco"));
Node.js
const stateQueryRes = await citiesRef.where('state', '==', 'CA').get(); const populationQueryRes = await citiesRef.where('population', '<', 1000000).get(); const nameQueryRes = await citiesRef.where('name', '>=', 'San Francisco').get();
Go
countryQuery := cities.Where("state", "==", "CA") popQuery := cities.Where("population", "<", 1000000) cityQuery := cities.Where("name", ">=", "San Francisco")
PHP
$stateQuery = $citiesRef->where('state', '=', 'CA'); $populationQuery = $citiesRef->where('population', '>', 1000000); $nameQuery = $citiesRef->where('name', '>=', 'San Francisco');
Unity
Query stateQuery = citiesRef.WhereEqualTo("State", "CA"); Query populationQuery = citiesRef.WhereGreaterThan("Population", 1000000); Query nameQuery = citiesRef.WhereGreaterThanOrEqualTo("Name", "San Francisco");
C#
Query stateQuery = citiesRef.WhereEqualTo("State", "CA"); Query populationQuery = citiesRef.WhereGreaterThan("Population", 1000000); Query nameQuery = citiesRef.WhereGreaterThanOrEqualTo("Name", "San Francisco");
Ruby
state_query = cities_ref.where "state", "=", "CA" population_query = cities_ref.where "population", ">", 1_000_000 name_query = cities_ref.where "name", ">=", "San Francisco"
Not equal (!=
)
Use the not equal (!=
) operator to return documents where the given field
exists and does not match the comparison value. For example:
Web
citiesRef.where("capital", "!=", false);
Swift
let notEqualQuery = citiesRef.whereField("capital", isNotEqualTo: false)
Objective-C
query = [citiesRef queryWhereField:@"capital" isNotEqualTo:@NO];
Java
citiesRef.whereNotEqualTo("capital", false);
Kotlin+KTX
citiesRef.whereNotEqualTo("capital", false)
Java
CollectionReference citiesRef = db.collection("cities"); Query query = citiesRef.whereNotEqualTo("capital", false);
Python
// Snippet not yet available
C++
// Snippet not yet available
Node.js
const capitalNotFalseRes = await citiesRef.where('capital', '!=', false).get();
Go
// Snippet not yet available
PHP
// Snippet not yet available
Unity
// Snippet not yet available
C#
// Snippet not yet available
Ruby
// Snippet not yet available
This query returns every city
document where the capital
field exists with a
value other than false
or null
. This includes city
documents where the
capital
field value equals true
or any non-boolean value besides null
.
This query does not return city
documents where the capital
field does not
exist. Not-equal (!=
) and not-in
queries exclude documents where the
given field does not exist.
A field exists when it's set to any value, including an empty string (""
),
null
, and NaN
(not a number). Note that null
field values do not
match !=
clauses, because x != null
evaluates to undefined
.
Limitations
Note the following limitations for !=
queries:
- Only documents where the given field exists can match the query.
- You can't combine
not-in
and!=
in a compound query. - In a compound query, range (
<
,<=
,>
,>=
) and not equals (!=
,not-in
) comparisons must all filter on the same field.
Array membership
You can use the array-contains
operator to filter based on array
values. For example:
Web v8
citiesRef.where("regions", "array-contains", "west_coast");
Web v9
import { query, where } from "firebase/firestore"; const q = query(citiesRef, where("regions", "array-contains", "west_coast"));
Swift
citiesRef .whereField("regions", arrayContains: "west_coast")
Objective-C
[citiesRef queryWhereField:@"state" arrayContains:@"west_coast"];
Java
CollectionReference citiesRef = db.collection("cities"); citiesRef.whereArrayContains("regions", "west_coast");
Kotlin+KTX
val citiesRef = db.collection("cities") citiesRef.whereArrayContains("regions", "west_coast")
Java
CollectionReference citiesRef = db.collection("cities"); Query westCoastQuery = citiesRef.whereArrayContains("regions", "west_coast");
Python
cities_ref = db.collection(u'cities') query = cities_ref.where(u'regions', u'array_contains', u'west_coast')
C++
// This is not yet supported.
Node.js
const westCoastCities = citiesRef.where('regions', 'array-contains', 'west_coast').get();
Go
query := cities.Where("regions", "array-contains", "west_coast").Documents(ctx)
PHP
$containsQuery = $citiesRef->where('regions', 'array-contains', 'west_coast');
Unity
CollectionReference citiesRef = db.Collection("cities"); Query arrayContainsQuery = citiesRef.WhereArrayContains("region", "west_coast");
C#
Query query = citiesRef.WhereArrayContains("Regions", "west_coast");
Ruby
cities_ref = firestore.col collection_path cities = cities_ref.where "regions", "array-contains", "west_coast"
This query returns every city
document where the regions
field is an array that
contains west_coast
. If the array has multiple instances of the value you
query on, the document is included in the results only once.
You can use at most one array-contains
clause per query. You can't combine
array-contains
with array-contains-any
.
in
, not-in
, and array-contains-any
Use the in
operator to combine up to 10 equality (==
) clauses on
the same field with a logical OR
. An in
query returns documents
where the given field matches any of the comparison values. For example:
Web
citiesRef.where('country', 'in', ['USA', 'Japan']);
Swift
let citiesRef = db.collection("cities") citiesRef.whereField("country", in: ["USA", "Japan"])
Objective-C
FIRCollectionReference *citiesRef = [self.db collectionWithPath:@"cities"]; [citiesRef queryWhereField:@"country" in:@[@"USA", @"Japan"]];
Java
CollectionReference citiesRef = db.collection("cities"); citiesRef.whereIn("country", Arrays.asList("USA", "Japan"));
Kotlin+KTX
val citiesRef = db.collection("cities") citiesRef.whereIn("country", listOf("USA", "Japan"))
Java
CollectionReference citiesRef = db.collection("cities"); Query query = citiesRef.whereIn("country", Arrays.asList("USA", "Japan"));
Python
cities_ref = db.collection(u'cities') query = cities_ref.where(u'country', u'in', [u'USA', u'Japan']) return query
C++
// This is not yet supported.
Node.js
const usaOrJapan = await citiesRef.where('country', 'in', ['USA', 'Japan']).get();
Go
cities := client.Collection("cities") query := cities.Where("country", "in", []string{"USA", "Japan"}).Documents(ctx)
PHP
// Snippet not yet available
Unity
CollectionReference citiesRef = db.Collection("cities"); ListcountriesList = new List<object>() {"USA", "Japan"}; Query whereInQuery = citiesRef.WhereIn("country", contriesList);
C#
Query query = citiesRef.WhereIn("Country", new[] { "USA", "Japan" });
Ruby
cities_ref = firestore.col collection_path usr_or_japan = cities_ref.where "country", "in", ["USA", "Japan"]
This query returns every city
document where the country
field is set
to USA
or Japan
. From the example data, this includes
the SF
, LA
, DC
, and TOK
documents.
not-in
Use the not-in
operator to combine up to 10 not equal (!=
) clauses on the
same field with a logical AND
. A not-in
query returns documents where the
given field exists, is not null
, and does not match any of the
comparison values. For example:
Web
citiesRef.where('country', 'not-in', ['USA', 'Japan']);
Swift
citiesRef.whereField("country", notIn: ["USA", "Japan"])
Objective-C
[citiesRef queryWhereField:@"country" notIn:@[@"USA", @"Japan"]];
Java
citiesRef.whereNotIn("country", Arrays.asList("USA", "Japan"));
Kotlin+KTX
citiesRef.whereNotIn("country", listOf("USA", "Japan"))
Java
CollectionReference citiesRef = db.collection("cities"); Query query = citiesRef.whereNotIn("country", Arrays.asList("USA", "Japan"));
Python
// Snippet not yet available
C++
// Snippet not yet available
Node.js
const notUsaOrJapan = await citiesRef.where('country', 'not-in', ['USA', 'Japan']).get();
Go
// Snippet not yet available
PHP
// Snippet not yet available
Unity
// Snippet not yet available
C#
// Snippet not yet available
Ruby
// Snippet not yet available
This query returns every city
document where the country
field exists and is
not set to USA
, Japan
, or null
. From the example data, this includes the
London
and Hong Kong
documents.
not-in
queries exclude documents where the
given field does not exist. A field exists when it's set to any value,
including an empty string (""
), null
, and NaN
(not a number). Note
that x != null
evaluates to undefined
. A not-in
query with
null
as one of the comparison values does not match any documents.
array-contains-any
Use the array-contains-any
operator to combine up to 10
array-contains
clauses on the same field with a logical OR
. An
array-contains-any
query returns documents where the given field is an array
that contains one or more of the comparison values:
Web
citiesRef.where('regions', 'array-contains-any', ['west_coast', 'east_coast']);
Swift
let citiesRef = db.collection("cities") citiesRef.whereField("regions", arrayContainsAny: ["west_coast", "east_coast"])
Objective-C
FIRCollectionReference *citiesRef = [self.db collectionWithPath:@"cities"]; [citiesRef queryWhereField:@"regions" arrayContainsAny:@[@"west_coast", @"east_coast"]];
Java
CollectionReference citiesRef = db.collection("cities"); citiesRef.whereArrayContainsAny("regions", Arrays.asList("west_coast", "east_coast"));
Kotlin+KTX
val citiesRef = db.collection("cities") citiesRef.whereArrayContainsAny("regions", listOf("west_coast", "east_coast"))
Java
CollectionReference citiesRef = db.collection("cities"); Query query = citiesRef.whereArrayContainsAny("regions", Arrays.asList("west_coast", "east_coast"));
Python
cities_ref = db.collection(u'cities') query = cities_ref.where( u'regions', u'array_contains_any', [u'west_coast', u'east_coast'] ) return query
C++
// This is not yet supported.
Node.js
const coastalCities = await citiesRef.where('regions', 'array-contains-any', ['west_coast', 'east_coast']).get();
Go
cities := client.Collection("cities") query := cities.Where("regions", "array-contains-any", []string{"west_coast", "east_coast"}).Documents(ctx)
PHP
// Snippet not yet available
Unity
CollectionReference citiesRef = db.Collection("cities"); ListregionsList = new List<object>() {"west_coast", "east_coast"}; Query arrayContainsAnyQuery = citiesRef.WhereArrayContainsAny("regions", regionsList);
C#
Query query = citiesRef.WhereArrayContainsAny("Regions", new[] { "west_coast", "east_coast" });
Ruby
cities_ref = firestore.col collection_path costal_cities = cities_ref.where "regions", "array-contains-any", ["west_coast", "east_coast"]
This query returns every city document where the region
field is an array
that contains west_coast
or east_coast
. From the example data, this includes
the SF
, LA
, and DC
documents.
Results from array-contains-any
are de-duped. Even if a document's array field
matches more than one of the comparison values, the result set includes that
document only once.
array-contains-any
always filters by the array data type. For example, the
query above would not return a city document where instead of an array, the
region
field is the string west_coast
.
You can use an array value as a comparison value for in
, but unlike
array-contains-any
, the clause matches for an exact match of array length,
order, and values. For example:
Web
citiesRef.where('region', 'in', [['west_coast', 'east_coast']]);
Swift
citiesRef.whereField("regions", in: [["west_coast"], ["east_coast"]]);
Objective-C
[citiesRef queryWhereField:@"regions" in:@[@[@"west_coast"], @[@"east_coast"]]];
Java
citiesRef.whereIn("regions", Arrays.asList(new String[]{"west_coast"}, new String[]{"east_coast"}));
Kotlin+KTX
citiesRef.whereIn("regions", listOf(arrayOf("west_coast"), arrayOf("east_coast")))
Java
CollectionReference citiesRef = db.collection("cities"); Query query = citiesRef.whereIn( "regions", Arrays.asList(Arrays.asList("west_coast"), Arrays.asList("east_coast")));
Python
cities_ref = db.collection(u'cities') query = cities_ref.where( u'regions', u'in', [[u'west_coast'], [u'east_coast']] ) return query
C++
// This is not yet supported.
Node.js
const exactlyOneCoast = await citiesRef.where('region', 'in', [['west_coast', 'east_coast']]).get();
Go
cities := client.Collection("cities") query := cities.Where("regions", "in", [][]string{{"west_coast"}, {"east_coast"}}).Documents(ctx)
PHP
// Snippet not yet available
Unity
// Not yet supported in the Unity SDK
C#
Query query = citiesRef.WhereIn("Regions", new[] { new[] { "west_coast" }, new[] { "east_coast" } });
Ruby
cities_ref = firestore.col collection_path exactly_one_cost = cities_ref.where "regions", "in", [["west_coast"], ["east_coast"]]
This query returns every city document where the region
field is an array
that contains exactly one element of either west_coast
or east_coast
.
From the example data, only the DC
document qualifies with its region
field
of ["east_coast"]
. The SF
document, however, does
not match because its region
field is ["west_coast", "norcal"]
.
Limitations
Note the following limitations for in
, not-in
, and array-contains-any
:
in
,not-in
, andarray-contains-any
support up to 10 comparison values.- You can use at most one
array-contains
clause per query. You can't combinearray-contains
witharray-contains-any
. - You can use at most one
in
,not-in
, orarray-contains-any
clause per query. You can't combine these operators in the same query. - You can't combine
not-in
with not equals!=
. - You can't order your query by a field included in an equality (
==
) orin
clause.
Compound queries
You can chain multiple equality operators (==
or array-contains
) methods to
create more specific queries (logical AND
). However, you must create a
composite index to combine equality operators with the inequality
operators, <
, <=
, >
, and !=
.
Web v8
citiesRef.where("state", "==", "CO").where("name", "==", "Denver"); citiesRef.where("state", "==", "CA").where("population", "<", 1000000);
Web v9
import { query, where } from "firebase/firestore"; const q1 = query(citiesRef, where("state", "==", "CO"), where("name", "==", "Denver")); const q2 = query(citiesRef, where("state", "==", "CA"), where("population", "<", 1000000));
Swift
citiesRef .whereField("state", isEqualTo: "CO") .whereField("name", isEqualTo: "Denver") citiesRef .whereField("state", isEqualTo: "CA") .whereField("population", isLessThan: 1000000)
Objective-C
[[citiesRef queryWhereField:@"state" isEqualTo:@"CO"] queryWhereField:@"name" isGreaterThanOrEqualTo:@"Denver"]; [[citiesRef queryWhereField:@"state" isEqualTo:@"CA"] queryWhereField:@"population" isLessThan:@1000000];
Java
citiesRef.whereEqualTo("state", "CO").whereEqualTo("name", "Denver"); citiesRef.whereEqualTo("state", "CA").whereLessThan("population", 1000000);
Kotlin+KTX
citiesRef.whereEqualTo("state", "CO").whereEqualTo("name", "Denver") citiesRef.whereEqualTo("state", "CA").whereLessThan("population", 1000000)
Java
Query chainedQuery1 = cities.whereEqualTo("state", "CO").whereEqualTo("name", "Denver");ndentation="auto" %}
Python
cities_ref = db.collection(u'cities') denver_query = cities_ref.where( u'state', u'==', u'CO').where(u'name', u'==', u'Denver') large_us_cities_query = cities_ref.where( u'state', u'==', u'CA').where(u'population', u'>', 1000000)
C++
cities_ref.WhereEqualTo("state", FieldValue::String("CO")) .WhereEqualTo("name", FieldValue::String("Denver")); cities_ref.WhereEqualTo("state", FieldValue::String("CA")) .WhereLessThan("population", FieldValue::Integer(1000000));
Node.js
citiesRef.where('state', '==', 'CO').where('name', '==', 'Denver');%}
Go
denverQuery := cities.Where("name", "==", "Denver").Where("state", "==", "CO") caliQuery := cities.Where("state", "==", "CA").Where("population", "<=", 1000000)
PHP
$chainedQuery = $citiesRef ->where('state', '=', 'CA') ->where('name', '=', 'San Francisco');
Unity
Query chainedQuery = citiesRef .WhereEqualTo("State", "CA") .WhereEqualTo("Name", "San Francisco");
C#
Query chainedQuery = citiesRef .WhereEqualTo("State", "CA") .WhereEqualTo("Name", "San Francisco");
Ruby
chained_query = cities_ref.where("state", "=", "CA").where("name", "=", "San Francisco")
You can perform range (<
, <=
, >
, >=
) or not equals (!=
)
comparisons only on a single field, and you can include at most one
array-contains
or array-contains-any
clause in a
compound query:
Valid: Range filters on only one field
Web v8
citiesRef.where("state", ">=", "CA").where("state", "<=", "IN"); citiesRef.where("state", "==", "CA").where("population", ">", 1000000);
Web v9
import { query, where } from "firebase/firestore"; const q1 = query(citiesRef, where("state", ">=", "CA"), where("state", "<=", "IN")); const q2 = query(citiesRef, where("state", "==", "CA"), where("population", ">", 1000000));
Swift
citiesRef .whereField("state", isGreaterThanOrEqualTo: "CA") .whereField("state", isLessThanOrEqualTo: "IN") citiesRef .whereField("state", isEqualTo: "CA") .whereField("population", isGreaterThan: 1000000)
Objective-C
[[citiesRef queryWhereField:@"state" isGreaterThanOrEqualTo:@"CA"] queryWhereField:@"state" isLessThanOrEqualTo:@"IN"]; [[citiesRef queryWhereField:@"state" isEqualTo:@"CA"] queryWhereField:@"population" isGreaterThan:@1000000];
Java
citiesRef.whereGreaterThanOrEqualTo("state", "CA") .whereLessThanOrEqualTo("state", "IN"); citiesRef.whereEqualTo("state", "CA") .whereGreaterThan("population", 1000000);
Kotlin+KTX
citiesRef.whereGreaterThanOrEqualTo("state", "CA") .whereLessThanOrEqualTo("state", "IN") citiesRef.whereEqualTo("state", "CA") .whereGreaterThan("population", 1000000)
Java
Query validQuery1 = cities.whereGreaterThanOrEqualTo("state", "CA").whereLessThanOrEqualTo("state", "IN"); Query validQuery2 = cities.whereEqualTo("state", "CA").whereGreaterThan("population", 1000000);
Python
cities_ref = db.collection(u'cities') cities_ref.where(u'state', u'>=', u'CA').where(u'state', u'<=', u'IN')
C++
cities_ref.WhereGreaterThanOrEqualTo("state", FieldValue::String("CA")) .WhereLessThanOrEqualTo("state", FieldValue::String("IN")); cities_ref.WhereEqualTo("state", FieldValue::String("CA")) .WhereGreaterThan("population", FieldValue::Integer(1000000));
Node.js
citiesRef.where('state', '>=', 'CA').where('state', '<=', 'IN'); citiesRef.where('state', '==', 'CA').where('population', '>', 1000000);
Go
stateQuery := cities.Where("state", ">=", "CA").Where("state", "<", "IN") populationQuery := cities.Where("state", "==", "CA").Where("population", ">", 1000000)
PHP
$rangeQuery = $citiesRef ->where('state', '>=', 'CA') ->where('state', '<=', 'IN');
Unity
Query rangeQuery = citiesRef .WhereGreaterThanOrEqualTo("State", "CA") .WhereLessThanOrEqualTo("State", "IN");
C#
Query rangeQuery = citiesRef .WhereGreaterThanOrEqualTo("State", "CA") .WhereLessThanOrEqualTo("State", "IN");
Ruby
range_query = cities_ref.where("state", ">=", "CA").where("state", "<=", "IN")
Invalid: Range filters on different fields
Web v8
citiesRef.where("state", ">=", "CA").where("population", ">", 100000);
Web v9
import { query, where } from "firebase/firestore"; const q = query(citiesRef, where("state", ">=", "CA"), where("population", ">", 100000));
Swift
citiesRef .whereField("state", isGreaterThanOrEqualTo: "CA") .whereField("population", isGreaterThan: 1000000)
Objective-C
[[citiesRef queryWhereField:@"state" isGreaterThanOrEqualTo:@"CA"] queryWhereField:@"population" isGreaterThan:@1000000];
Java
citiesRef.whereGreaterThanOrEqualTo("state", "CA").whereGreaterThan("population", 100000);
Kotlin+KTX
citiesRef.whereGreaterThanOrEqualTo("state", "CA") .whereGreaterThan("population", 100000)
Java
Query invalidRangeQuery = cities.whereGreaterThanOrEqualTo("state", "CA").whereGreaterThan("population", 100000);
Python
cities_ref = db.collection(u'cities') cities_ref.where( u'state', u'>=', u'CA').where(u'population', u'>=', 1000000)
C++
// BAD EXAMPLE -- will crash the program: cities_ref.WhereGreaterThanOrEqualTo("state", FieldValue::String("CA")) .WhereGreaterThan("population", FieldValue::Integer(100000));
Node.js
citiesRef.where('state', '>=', 'CA').where('population', '>', 1000000);
Go
query := cities.Where("state", ">=", "CA").Where("population", ">", 1000000)
PHP
$invalidRangeQuery = $citiesRef ->where('state', '>=', 'CA') ->where('population', '>', 1000000);
Unity
Query invalidRangeQuery = citiesRef .WhereGreaterThanOrEqualTo("State", "CA") .WhereGreaterThan("Population", 1000000);
C#
Query invalidRangeQuery = citiesRef .WhereGreaterThanOrEqualTo("State", "CA") .WhereGreaterThan("Population", 1000000);
Ruby
invalid_range_query = cities_ref.where("state", ">=", "CA").where("population", ">", 1_000_000)
Collection group queries
A collection group consists of all collections with the same ID. By default, queries retrieve results from a single collection in your database. Use a collection group query to retrieve documents from a collection group instead of from a single collection.
For example, you can create a landmarks
collection group by adding a landmarks
subcollection to each city:
Web
var citiesRef = db.collection('cities'); var landmarks = Promise.all([ citiesRef.doc('SF').collection('landmarks').doc().set({ name: 'Golden Gate Bridge', type: 'bridge' }), citiesRef.doc('SF').collection('landmarks').doc().set({ name: 'Legion of Honor', type: 'museum' }), citiesRef.doc('LA').collection('landmarks').doc().set({ name: 'Griffith Park', type: 'park' }), citiesRef.doc('LA').collection('landmarks').doc().set({ name: 'The Getty', type: 'museum' }), citiesRef.doc('DC').collection('landmarks').doc().set({ name: 'Lincoln Memorial', type: 'memorial' }), citiesRef.doc('DC').collection('landmarks').doc().set({ name: 'National Air and Space Museum', type: 'museum' }), citiesRef.doc('TOK').collection('landmarks').doc().set({ name: 'Ueno Park', type: 'park' }), citiesRef.doc('TOK').collection('landmarks').doc().set({ name: 'National Museum of Nature and Science', type: 'museum' }), citiesRef.doc('BJ').collection('landmarks').doc().set({ name: 'Jingshan Park', type: 'park' }), citiesRef.doc('BJ').collection('landmarks').doc().set({ name: 'Beijing Ancient Observatory', type: 'museum' }) ]);
Swift
let citiesRef = db.collection("cities") var data = ["name": "Golden Gate Bridge", "type": "bridge"] citiesRef.document("SF").collection("landmarks").addDocument(data: data) data = ["name": "Legion of Honor", "type": "museum"] citiesRef.document("SF").collection("landmarks").addDocument(data: data) data = ["name": "Griffith Park", "type": "park"] citiesRef.document("LA").collection("landmarks").addDocument(data: data) data = ["name": "The Getty", "type": "museum"] citiesRef.document("LA").collection("landmarks").addDocument(data: data) data = ["name": "Lincoln Memorial", "type": "memorial"] citiesRef.document("DC").collection("landmarks").addDocument(data: data) data = ["name": "National Air and Space Museum", "type": "museum"] citiesRef.document("DC").collection("landmarks").addDocument(data: data) data = ["name": "Ueno Park", "type": "park"] citiesRef.document("TOK").collection("landmarks").addDocument(data: data) data = ["name": "National Museum of Nature and Science", "type": "museum"] citiesRef.document("TOK").collection("landmarks").addDocument(data: data) data = ["name": "Jingshan Park", "type": "park"] citiesRef.document("BJ").collection("landmarks").addDocument(data: data) data = ["name": "Beijing Ancient Observatory", "type": "museum"] citiesRef.document("BJ").collection("landmarks").addDocument(data: data)
Objective-C
FIRCollectionReference *citiesRef = [self.db collectionWithPath:@"cities"]; NSDictionary *data = @{@"name": @"Golden Gate Bridge", @"type": @"bridge"}; [[[citiesRef documentWithPath:@"SF"] collectionWithPath:@"landmarks"] addDocumentWithData:data]; data = @{@"name": @"Legion of Honor", @"type": @"museum"}; [[[citiesRef documentWithPath:@"SF"] collectionWithPath:@"landmarks"] addDocumentWithData:data]; data = @{@"name": @"Griffith Park", @"type": @"park"}; [[[citiesRef documentWithPath:@"LA"] collectionWithPath:@"landmarks"] addDocumentWithData:data]; data = @{@"name": @"The Getty", @"type": @"museum"}; [[[citiesRef documentWithPath:@"LA"] collectionWithPath:@"landmarks"] addDocumentWithData:data]; data = @{@"name": @"Lincoln Memorial", @"type": @"memorial"}; [[[citiesRef documentWithPath:@"DC"] collectionWithPath:@"landmarks"] addDocumentWithData:data]; data = @{@"name": @"National Air and Space Museum", @"type": @"museum"}; [[[citiesRef documentWithPath:@"DC"] collectionWithPath:@"landmarks"] addDocumentWithData:data]; data = @{@"name": @"Ueno Park", @"type": @"park"}; [[[citiesRef documentWithPath:@"TOK"] collectionWithPath:@"landmarks"] addDocumentWithData:data]; data = @{@"name": @"National Museum of Nature and Science", @"type": @"museum"}; [[[citiesRef documentWithPath:@"TOK"] collectionWithPath:@"landmarks"] addDocumentWithData:data]; data = @{@"name": @"Jingshan Park", @"type": @"park"}; [[[citiesRef documentWithPath:@"BJ"] collectionWithPath:@"landmarks"] addDocumentWithData:data]; data = @{@"name": @"Beijing Ancient Observatory", @"type": @"museum"}; [[[citiesRef documentWithPath:@"BJ"] collectionWithPath:@"landmarks"] addDocumentWithData:data];
Java
CollectionReference citiesRef = db.collection("cities"); Map<String, Object> ggbData = new HashMap<>(); ggbData.put("name", "Golden Gate Bridge"); ggbData.put("type", "bridge"); citiesRef.document("SF").collection("landmarks").add(ggbData); Map<String, Object> lohData = new HashMap<>(); lohData.put("name", "Legion of Honor"); lohData.put("type", "museum"); citiesRef.document("SF").collection("landmarks").add(lohData); Map<String, Object> gpData = new HashMap<>(); gpData.put("name", "Griffith Park"); gpData.put("type", "park"); citiesRef.document("LA").collection("landmarks").add(gpData); Map<String, Object> tgData = new HashMap<>(); tgData.put("name", "The Getty"); tgData.put("type", "museum"); citiesRef.document("LA").collection("landmarks").add(tgData); Map<String, Object> lmData = new HashMap<>(); lmData.put("name", "Lincoln Memorial"); lmData.put("type", "memorial"); citiesRef.document("DC").collection("landmarks").add(lmData); Map<String, Object> nasaData = new HashMap<>(); nasaData.put("name", "National Air and Space Museum"); nasaData.put("type", "museum"); citiesRef.document("DC").collection("landmarks").add(nasaData); Map<String, Object> upData = new HashMap<>(); upData.put("name", "Ueno Park"); upData.put("type", "park"); citiesRef.document("TOK").collection("landmarks").add(upData); Map<String, Object> nmData = new HashMap<>(); nmData.put("name", "National Museum of Nature and Science"); nmData.put("type", "museum"); citiesRef.document("TOK").collection("landmarks").add(nmData); Map<String, Object> jpData = new HashMap<>(); jpData.put("name", "Jingshan Park"); jpData.put("type", "park"); citiesRef.document("BJ").collection("landmarks").add(jpData); Map<String, Object> baoData = new HashMap<>(); baoData.put("name", "Beijing Ancient Observatory"); baoData.put("type", "museum"); citiesRef.document("BJ").collection("landmarks").add(baoData);
Kotlin+KTX
val citiesRef = db.collection("cities") val ggbData = mapOf( "name" to "Golden Gate Bridge", "type" to "bridge" ) citiesRef.document("SF").collection("landmarks").add(ggbData) val lohData = mapOf( "name" to "Legion of Honor", "type" to "museum" ) citiesRef.document("SF").collection("landmarks").add(lohData) val gpData = mapOf( "name" to "Griffth Park", "type" to "park" ) citiesRef.document("LA").collection("landmarks").add(gpData) val tgData = mapOf( "name" to "The Getty", "type" to "museum" ) citiesRef.document("LA").collection("landmarks").add(tgData) val lmData = mapOf( "name" to "Lincoln Memorial", "type" to "memorial" ) citiesRef.document("DC").collection("landmarks").add(lmData) val nasaData = mapOf( "name" to "National Air and Space Museum", "type" to "museum" ) citiesRef.document("DC").collection("landmarks").add(nasaData) val upData = mapOf( "name" to "Ueno Park", "type" to "park" ) citiesRef.document("TOK").collection("landmarks").add(upData) val nmData = mapOf( "name" to "National Musuem of Nature and Science", "type" to "museum" ) citiesRef.document("TOK").collection("landmarks").add(nmData) val jpData = mapOf( "name" to "Jingshan Park", "type" to "park" ) citiesRef.document("BJ").collection("landmarks").add(jpData) val baoData = mapOf( "name" to "Beijing Ancient Observatory", "type" to "musuem" ) citiesRef.document("BJ").collection("landmarks").add(baoData)
Java
CollectionReference cities = db.collection("cities"); final List<ApiFuture<WriteResult>> futures = Arrays.asList( cities .document("SF") .collection("landmarks") .document() .set( new HashMap<String, String>() { { put("name", "Golden Gate Bridge"); put("type", "bridge"); } }), cities .document("SF") .collection("landmarks") .document() .set( new HashMap<String, String>() { { put("name", "Legion of Honor"); put("type", "museum"); } }), cities .document("LA") .collection("landmarks") .document() .set( new HashMap<String, String>() { { put("name", "Griffith Park"); put("type", "park"); } }), cities .document("LA") .collection("landmarks") .document() .set( new HashMap<String, String>() { { put("name", "The Getty"); put("type", "museum"); } }), cities .document("DC") .collection("landmarks") .document() .set( new HashMap<String, String>() { { put("name", "Lincoln Memorial"); put("type", "memorial"); } }), cities .document("DC") .collection("landmarks") .document() .set( new HashMap<String, String>() { { put("name", "National Air and Space Museum"); put("type", "museum"); } }), cities .document("TOK") .collection("landmarks") .document() .set( new HashMap<String, String>() { { put("name", "Ueno Park"); put("type", "park"); } }), cities .document("TOK") .collection("landmarks") .document() .set( new HashMap<String, String>() { { put("name", "National Museum of Nature and Science"); put("type", "museum"); } }), cities .document("BJ") .collection("landmarks") .document() .set( new HashMap<String, String>() { { put("name", "Jingshan Park"); put("type", "park"); } }), cities .document("BJ") .collection("landmarks") .document() .set( new HashMap<String, String>() { { put("name", "Beijing Ancient Observatory"); put("type", "museum"); } })); final List<WriteResult> landmarks = ApiFutures.allAsList(futures).get();
Python
cities = db.collection(u'cities') sf_landmarks = cities.document(u'SF').collection(u'landmarks') sf_landmarks.document().set({ u'name': u'Golden Gate Bridge', u'type': u'bridge' }) sf_landmarks.document().set({ u'name': u'Legion of Honor', u'type': u'museum' }) la_landmarks = cities.document(u'LA').collection(u'landmarks') la_landmarks.document().set({ u'name': u'Griffith Park', u'type': u'park' }) la_landmarks.document().set({ u'name': u'The Getty', u'type': u'museum' }) dc_landmarks = cities.document(u'DC').collection(u'landmarks') dc_landmarks.document().set({ u'name': u'Lincoln Memorial', u'type': u'memorial' }) dc_landmarks.document().set({ u'name': u'National Air and Space Museum', u'type': u'museum' }) tok_landmarks = cities.document(u'TOK').collection(u'landmarks') tok_landmarks.document().set({ u'name': u'Ueno Park', u'type': u'park' }) tok_landmarks.document().set({ u'name': u'National Museum of Nature and Science', u'type': u'museum' }) bj_landmarks = cities.document(u'BJ').collection(u'landmarks') bj_landmarks.document().set({ u'name': u'Jingshan Park', u'type': u'park' }) bj_landmarks.document().set({ u'name': u'Beijing Ancient Observatory', u'type': u'museum' })
C++
// This is not yet supported.
Node.js
const citiesRef = db.collection('cities'); await citiesRef.doc('SF').collection('landmarks').doc().set({ name: 'Golden Gate Bridge', type: 'bridge' }); await citiesRef.doc('SF').collection('landmarks').doc().set({ name: 'Legion of Honor', type: 'museum' }); await citiesRef.doc('LA').collection('landmarks').doc().set({ name: 'Griffith Park', type: 'park' }); await citiesRef.doc('LA').collection('landmarks').doc().set({ name: 'The Getty', type: 'museum' }); await citiesRef.doc('DC').collection('landmarks').doc().set({ name: 'Lincoln Memorial', type: 'memorial' }); await citiesRef.doc('DC').collection('landmarks').doc().set({ name: 'National Air and Space Museum', type: 'museum' }); await citiesRef.doc('TOK').collection('landmarks').doc().set({ name: 'Ueno Park', type: 'park' }); await citiesRef.doc('TOK').collection('landmarks').doc().set({ name: 'National Museum of Nature and Science', type: 'museum' }); await citiesRef.doc('BJ').collection('landmarks').doc().set({ name: 'Jingshan Park', type: 'park' }); await citiesRef.doc('BJ').collection('landmarks').doc().set({ name: 'Beijing Ancient Observatory', type: 'museum' });
Go
import ( "context" "fmt" "cloud.google.com/go/firestore" ) // collectionGroupSetup sets up a collection group to query. func collectionGroupSetup(projectID, cityCollection string) error { ctx := context.Background() client, err := firestore.NewClient(ctx, projectID) if err != nil { return fmt.Errorf("firestore.NewClient: %v", err) } defer client.Close() landmarks := []struct { city, name, t string }{ {"SF", "Golden Gate Bridge", "bridge"}, {"SF", "Legion of Honor", "museum"}, {"LA", "Griffith Park", "park"}, {"LA", "The Getty", "museum"}, {"DC", "Lincoln Memorial", "memorial"}, {"DC", "National Air and Space Museum", "museum"}, {"TOK", "Ueno Park", "park"}, {"TOK", "National Museum of Nature and Science", "museum"}, {"BJ", "Jingshan Park", "park"}, {"BJ", "Beijing Ancient Observatory", "museum"}, } cities := client.Collection(cityCollection) for _, l := range landmarks { if _, err := cities.Doc(l.city).Collection("landmarks").NewDoc().Set(ctx, map[string]string{ "name": l.name, "type": l.t, }); err != nil { return fmt.Errorf("Set: %v", err) } } return nil }
PHP
// Snippet not yet available
Unity
// Not yet supported in the Unity SDK
C#
await citiesRef.Document("SF").Collection("landmarks").Document() .CreateAsync(new { Name = "Golden Gate Bridge", Type = "bridge" }); await citiesRef.Document("SF").Collection("landmarks").Document() .CreateAsync(new { Name = "Legion of Honor", Type = "museum" }); await citiesRef.Document("LA").Collection("landmarks").Document() .CreateAsync(new { Name = "Griffith Park", Type = "park" }); await citiesRef.Document("DC").Collection("landmarks").Document() .CreateAsync(new { Name = "Lincoln Memorial", Type = "memorial" }); await citiesRef.Document("DC").Collection("landmarks").Document() .CreateAsync(new { Name = "National Air And Space Museum", Type = "museum" }); await citiesRef.Document("TOK").Collection("landmarks").Document() .CreateAsync(new { Name = "Ueno Park", Type = "park" }); await citiesRef.Document("TOK").Collection("landmarks").Document() .CreateAsync(new { Name = "National Museum of Nature and Science", Type = "museum" }); await citiesRef.Document("BJ").Collection("landmarks").Document() .CreateAsync(new { Name = "Jingshan Park", Type = "park" }); await citiesRef.Document("BJ").Collection("landmarks").Document() .CreateAsync(new { Name = "Beijing Ancient Observatory", Type = "museum" });
Ruby
cities_ref = firestore.col collection_path sf_landmarks = cities_ref.document("SF").collection("landmarks") sf_landmarks.document.set( { name: "Golden Gate Bridge", type: "bridge" } ) sf_landmarks.document.set( { name: "Legion of Honor", type: "museum" } ) la_landmarks = cities_ref.document("LA").collection("landmarks") la_landmarks.document.set( { name: "Griffith Park", type: "park" } ) la_landmarks.document.set( { name: "The Getty", type: "museum" } ) dc_landmarks = cities_ref.document("DC").collection("landmarks") dc_landmarks.document.set( { name: "Lincoln Memorial", type: "memorial" } ) dc_landmarks.document.set( { name: "National Air and Space Museum", type: "museum" } ) tok_landmarks = cities_ref.document("TOK").collection("landmarks") tok_landmarks.document.set( { name: "Ueno Park", type: "park" } ) tok_landmarks.document.set( { name: "National Museum of Nature and Science", type: "museum" } ) bj_landmarks = cities_ref.document("BJ").collection("landmarks") bj_landmarks.document.set( { name: "Jingshan Park", type: "park" } ) bj_landmarks.document.set( { name: "Beijing Ancient Observatory", type: "museum" } )
We can use the simple and compound query described earlier to query a single
city's landmarks
subcollection, but you might also want to retrieve
results from every city's landmarks
subcollection at once.
The landmarks
collection group consists of all collections with the ID
landmarks
, and you can query it using a collection group query. For example,
this collection group query retrieves all museum
landmarks across all cities:
Web
->var museums = db.collectionGroup('landmarks').where('type', '==', 'museum'); museums.get().then((querySnapshot) => { querySnapshot.forEach((doc) => { console.log(doc.id, ' => ', doc.data()); }); });
Swift
db.collectionGroup("landmarks").whereField("type", isEqualTo: "museum").getDocuments { (snapshot, error) in // ... }
Objective-C
[[[self.db collectionGroupWithID:@"landmarks"] queryWhereField:@"type" isEqualTo:@"museum"] getDocumentsWithCompletion:^(FIRQuerySnapshot *snapshot, NSError *error) { // ... }];
Java
db.collectionGroup("landmarks").whereEqualTo("type", "museum").get() .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() { @Override public void onSuccess(QuerySnapshot queryDocumentSnapshots) { // ... } });
Kotlin+KTX
db.collectionGroup("landmarks").whereEqualTo("type", "museum").get() .addOnSuccessListener { queryDocumentSnapshots -> // ... }
Java
final Query museums = db.collectionGroup("landmarks").whereEqualTo("type", "museum"); final ApiFuture<QuerySnapshot> querySnapshot = museums.get(); for (DocumentSnapshot document : querySnapshot.get().getDocuments()) { System.out.println(document.getId()); }
Python
museums = db.collection_group(u'landmarks')\ .where(u'type', u'==', u'museum') docs = museums.stream() for doc in docs: print(f'{doc.id} => {doc.to_dict()}')
C++
// This is not yet supported.
Node.js
const querySnapshot = await db.collectionGroup('landmarks').where('type', '==', 'museum').get(); querySnapshot.forEach((doc) => { console.log(doc.id, ' => ', doc.data()); });
Go
import ( "context" "fmt" "io" "cloud.google.com/go/firestore" "google.golang.org/api/iterator" ) // collectionGroupQuery runs a collection group query over the data created by // collectionGroupSetup. func collectionGroupQuery(w io.Writer, projectID string) error { ctx := context.Background() client, err := firestore.NewClient(ctx, projectID) if err != nil { return fmt.Errorf("firestore.NewClient: %v", err) } defer client.Close() it := client.CollectionGroup("landmarks").Where("type", "==", "museum").Documents(ctx) for { doc, err := it.Next() if err == iterator.Done { break } if err != nil { return err } fmt.Fprintf(w, "%s: %s", doc.Ref.ID, doc.Data()["name"]) } return nil }
PHP
// Snippet not yet available
Unity
// Not yet supported in the Unity SDK
C#
Query museums = db.CollectionGroup("landmarks").WhereEqualTo("Type", "museum"); QuerySnapshot querySnapshot = await museums.GetSnapshotAsync(); foreach (DocumentSnapshot document in querySnapshot.Documents) { Console.WriteLine($"{document.Reference.Path}: {document.GetValue<string>("Name")}"); }
Ruby
museums = firestore.collection_group("landmarks").where("type", "==", "museum") museums.get do |museum| puts "#{museum[:type]} name is #{museum[:name]}." end
Before using a collection group query, you must create an index that supports your collection group query. You can create an index through an error message, the console, or the Firebase CLI.
For the web and mobile SDKs, you must also create rules that allow your collection group queries.
Query limitations
The following list summarizes Cloud Firestore query limitations:
- Cloud Firestore provides limited support for logical
OR
queries. Thein
, andarray-contains-any
operators support a logicalOR
of up to 10 equality (==
) orarray-contains
conditions on a single field. For other cases, create a separate query for eachOR
condition and merge the query results in your app. - In a compound query, range (
<
,<=
,>
,>=
) and 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 combinearray-contains
witharray-contains-any
. - You can use at most one
in
,not-in
, orarray-contains-any
clause per query. You can't combinein
,not-in
, andarray-contains-any
in the same query. - You can't order your query by a field included in an equality (
==
) orin
clause.