Hay dos maneras de recuperar datos almacenados en Cloud Firestore. Ambos métodos puede usarse con documentos, colecciones de documentos o resultados de consultas:
- Llamar a un método para obtener los datos.
- Configurar un objeto de escucha para recibir eventos de cambios de datos.
Cuando configuras un objeto de escucha, Cloud Firestore le envía una instantánea inicial de los datos y, luego, otra instantánea cada vez que se modifica el documento.
Datos de ejemplo
Para comenzar, escribe algunos datos sobre ciudades para que podamos ver las distintas maneras de leerlos:
Web
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"] });
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 operation 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 }); await citiesRef.doc('LA').set({ name: 'Los Angeles', state: 'CA', country: 'USA', capital: false, population: 3900000 }); await citiesRef.doc('DC').set({ name: 'Washington, D.C.', state: null, country: 'USA', capital: true, population: 680000 }); await citiesRef.doc('TOK').set({ name: 'Tokyo', state: null, country: 'Japan', capital: true, population: 9000000 }); await citiesRef.doc('BJ').set({ name: 'Beijing', state: null, country: 'China', capital: true, population: 21500000 });
Go
cities := []struct { id string c City }{ {id: "SF", c: City{Name: "San Francisco", State: "CA", Country: "USA", Capital: false, Population: 860000}}, {id: "LA", c: City{Name: "Los Angeles", State: "CA", Country: "USA", Capital: false, Population: 3900000}}, {id: "DC", c: City{Name: "Washington D.C.", Country: "USA", Capital: true, Population: 680000}}, {id: "TOK", c: City{Name: "Tokyo", Country: "Japan", Capital: true, Population: 9000000}}, {id: "BJ", c: City{Name: "Beijing", Country: "China", Capital: true, Population: 21500000}}, } for _, c := range cities { _, err := client.Collection("cities").Doc(c.id).Set(ctx, c.c) if err != nil { return err } }
PHP
$citiesRef = $db->collection('cities'); $citiesRef->document('SF')->set([ 'name' => 'San Francisco', 'state' => 'CA', 'country' => 'USA', 'capital' => false, 'population' => 860000 ]); $citiesRef->document('LA')->set([ 'name' => 'Los Angeles', 'state' => 'CA', 'country' => 'USA', 'capital' => false, 'population' => 3900000 ]); $citiesRef->document('DC')->set([ 'name' => 'Washington D.C.', 'state' => null, 'country' => 'USA', 'capital' => true, 'population' => 680000 ]); $citiesRef->document('TOK')->set([ 'name' => 'Tokyo', 'state' => null, 'country' => 'Japan', 'capital' => true, 'population' => 9000000 ]); $citiesRef->document('BJ')->set([ 'name' => 'Beijing', 'state' => null, 'country' => 'China', 'capital' => true, 'population' => 21500000 ]); 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 } }).ContinueWithOnMainThread(task => citiesRef.Document("LA").SetAsync(new Dictionary<string, object>(){ { "Name", "Los Angeles" }, { "State", "CA" }, { "Country", "USA" }, { "Capital", false }, { "Population", 3900000 } }) ).ContinueWithOnMainThread(task => citiesRef.Document("DC").SetAsync(new Dictionary<string, object>(){ { "Name", "Washington D.C." }, { "State", null }, { "Country", "USA" }, { "Capital", true }, { "Population", 680000 } }) ).ContinueWithOnMainThread(task => citiesRef.Document("TOK").SetAsync(new Dictionary<string, object>(){ { "Name", "Tokyo" }, { "State", null }, { "Country", "Japan" }, { "Capital", true }, { "Population", 9000000 } }) ).ContinueWithOnMainThread(task => citiesRef.Document("BJ").SetAsync(new Dictionary<string, object>(){ { "Name", "Beijing" }, { "State", null }, { "Country", "China" }, { "Capital", true }, { "Population", 21500000 } }) );
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 } }); await citiesRef.Document("LA").SetAsync(new Dictionary<string, object>(){ { "Name", "Los Angeles" }, { "State", "CA" }, { "Country", "USA" }, { "Capital", false }, { "Population", 3900000 } }); await citiesRef.Document("DC").SetAsync(new Dictionary<string, object>(){ { "Name", "Washington D.C." }, { "State", null }, { "Country", "USA" }, { "Capital", true }, { "Population", 680000 } }); await citiesRef.Document("TOK").SetAsync(new Dictionary<string, object>(){ { "Name", "Tokyo" }, { "State", null }, { "Country", "Japan" }, { "Capital", true }, { "Population", 9000000 } }); await citiesRef.Document("BJ").SetAsync(new Dictionary<string, object>(){ { "Name", "Beijing" }, { "State", null }, { "Country", "China" }, { "Capital", true }, { "Population", 21500000 } }); 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 ) cities_ref.doc("LA").set( name: "Los Angeles", state: "CA", country: "USA", capital: false, population: 3_900_000 ) cities_ref.doc("DC").set( name: "Washington D.C.", state: nil, country: "USA", capital: true, population: 680_000 ) cities_ref.doc("TOK").set( name: "Tokyo", state: nil, country: "Japan", capital: true, population: 9_000_000 ) cities_ref.doc("BJ").set( name: "Beijing", state: nil, country: "China", capital: true, population: 21_500_000 )
Obtén un documento
El siguiente ejemplo muestra cómo recuperar el contenido de un documento con get()
:
Web
var docRef = db.collection("cities").doc("SF"); docRef.get().then((doc) => { if (doc.exists) { console.log("Document data:", doc.data()); } else { // doc.data() will be undefined in this case console.log("No such document!"); } }).catch((error) => { console.log("Error getting document:", error); });
Swift
let docRef = db.collection("cities").document("SF") docRef.getDocument { (document, error) in if let document = document, document.exists { let dataDescription = document.data().map(String.init(describing:)) ?? "nil" print("Document data: \(dataDescription)") } else { print("Document does not exist") } }
Objective‑C
FIRDocumentReference *docRef = [[self.db collectionWithPath:@"cities"] documentWithPath:@"SF"]; [docRef getDocumentWithCompletion:^(FIRDocumentSnapshot *snapshot, NSError *error) { if (snapshot.exists) { // Document data may be nil if the document exists but has no keys or values. NSLog(@"Document data: %@", snapshot.data); } else { NSLog(@"Document does not exist"); } }];
Java
DocumentReference docRef = db.collection("cities").document("SF"); docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() { @Override public void onComplete(@NonNull Task<DocumentSnapshot> task) { if (task.isSuccessful()) { DocumentSnapshot document = task.getResult(); if (document.exists()) { Log.d(TAG, "DocumentSnapshot data: " + document.getData()); } else { Log.d(TAG, "No such document"); } } else { Log.d(TAG, "get failed with ", task.getException()); } } });
Kotlin+KTX
val docRef = db.collection("cities").document("SF") docRef.get() .addOnSuccessListener { document -> if (document != null) { Log.d(TAG, "DocumentSnapshot data: ${document.data}") } else { Log.d(TAG, "No such document") } } .addOnFailureListener { exception -> Log.d(TAG, "get failed with ", exception) }
Java
DocumentReference docRef = db.collection("cities").document("SF"); // asynchronously retrieve the document ApiFuture<DocumentSnapshot> future = docRef.get(); // ... // future.get() blocks on response DocumentSnapshot document = future.get(); if (document.exists()) { System.out.println("Document data: " + document.getData()); } else { System.out.println("No such document!"); }
Python
doc_ref = db.collection(u'cities').document(u'SF') doc = doc_ref.get() if doc.exists: print(f'Document data: {doc.to_dict()}') else: print(u'No such document!')
C++
DocumentReference doc_ref = db->Collection("cities").Document("SF"); doc_ref.Get().OnCompletion([](const Future<DocumentSnapshot>& future) { if (future.error() == Error::kErrorOk) { const DocumentSnapshot& document = *future.result(); if (document.exists()) { std::cout << "DocumentSnapshot id: " << document.id() << '\n'; } else { std::cout << "no such document\n"; } } else { std::cout << "Get failed with: " << future.error_message() << '\n'; } });
Node.js
const cityRef = db.collection('cities').doc('SF'); const doc = await cityRef.get(); if (!doc.exists) { console.log('No such document!'); } else { console.log('Document data:', doc.data()); }
Go
dsnap, err := client.Collection("cities").Doc("SF").Get(ctx) if err != nil { return nil, err } m := dsnap.Data() fmt.Printf("Document data: %#v\n", m)
PHP
$docRef = $db->collection('cities')->document('SF'); $snapshot = $docRef->snapshot(); if ($snapshot->exists()) { printf('Document data:' . PHP_EOL); print_r($snapshot->data()); } else { printf('Document %s does not exist!' . PHP_EOL, $snapshot->id()); }
Unity
DocumentReference docRef = db.Collection("cities").Document("SF"); docRef.GetSnapshotAsync().ContinueWithOnMainThread(task => { DocumentSnapshot snapshot = task.Result; if (snapshot.Exists) { Debug.Log(String.Format("Document data for {0} document:", snapshot.Id)); Dictionary<string, object> city = snapshot.ToDictionary(); foreach (KeyValuePair<string, object> pair in city) { Debug.Log(String.Format("{0}: {1}", pair.Key, pair.Value)); } } else { Debug.Log(String.Format("Document {0} does not exist!", snapshot.Id)); } });
C#
DocumentReference docRef = db.Collection("cities").Document("SF"); DocumentSnapshot snapshot = await docRef.GetSnapshotAsync(); if (snapshot.Exists) { Console.WriteLine("Document data for {0} document:", snapshot.Id); Dictionary<string, object> city = snapshot.ToDictionary(); foreach (KeyValuePair<string, object> pair in city) { Console.WriteLine("{0}: {1}", pair.Key, pair.Value); } } else { Console.WriteLine("Document {0} does not exist!", snapshot.Id); }
Ruby
doc_ref = firestore.doc "#{collection_path}/SF" snapshot = doc_ref.get if snapshot.exists? puts "#{snapshot.document_id} data: #{snapshot.data}." else puts "Document #{snapshot.document_id} does not exist!" end
Opciones de origen
En el caso de las plataformas con soporte sin conexión, puedes configurar la opción source
para controlar el modo en que una llamada a get
usa la caché sin conexión.
Según la configuración predeterminada, la llamada a get
intentará recuperar la instantánea más reciente del documento a partir de la base de datos En plataformas con soporte sin conexión, la biblioteca cliente usará la caché sin conexión si la red no está disponible o si se agota el tiempo de espera de la solicitud.
Puedes especificar la opción source
en una llamada a get()
para cambiar el comportamiento predeterminado. Es posible recuperar las instantáneas solo de la base de datos y pasar por alto la caché sin conexión, o bien recuperarlas solo de la caché mencionada. Por ejemplo:
Web
var docRef = db.collection("cities").doc("SF"); // Valid options for source are 'server', 'cache', or // 'default'. See https://firebase.google.com/docs/reference/js/firebase.firestore.GetOptions // for more information. var getOptions = { source: 'cache' }; // Get a document, forcing the SDK to fetch from the offline cache. docRef.get(getOptions).then((doc) => { // Document was found in the cache. If no cached document exists, // an error will be returned to the 'catch' block below. console.log("Cached document data:", doc.data()); }).catch((error) => { console.log("Error getting cached document:", error); });
Swift
let docRef = db.collection("cities").document("SF") // Force the SDK to fetch the document from the cache. Could also specify // FirestoreSource.server or FirestoreSource.default. docRef.getDocument(source: .cache) { (document, error) in if let document = document { let dataDescription = document.data().map(String.init(describing:)) ?? "nil" print("Cached document data: \(dataDescription)") } else { print("Document does not exist in cache") } }
Objective‑C
FIRDocumentReference *docRef = [[self.db collectionWithPath:@"cities"] documentWithPath:@"SF"]; // Force the SDK to fetch the document from the cache. Could also specify // FIRFirestoreSourceServer or FIRFirestoreSourceDefault. [docRef getDocumentWithSource:FIRFirestoreSourceCache completion:^(FIRDocumentSnapshot *snapshot, NSError *error) { if (snapshot != NULL) { // The document data was found in the cache. NSLog(@"Cached document data: %@", snapshot.data); } else { // The document data was not found in the cache. NSLog(@"Document does not exist in cache: %@", error); } }];
Java
DocumentReference docRef = db.collection("cities").document("SF"); // Source can be CACHE, SERVER, or DEFAULT. Source source = Source.CACHE; // Get the document, forcing the SDK to use the offline cache docRef.get(source).addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() { @Override public void onComplete(@NonNull Task<DocumentSnapshot> task) { if (task.isSuccessful()) { // Document found in the offline cache DocumentSnapshot document = task.getResult(); Log.d(TAG, "Cached document data: " + document.getData()); } else { Log.d(TAG, "Cached get failed: ", task.getException()); } } });
Kotlin+KTX
val docRef = db.collection("cities").document("SF") // Source can be CACHE, SERVER, or DEFAULT. val source = Source.CACHE // Get the document, forcing the SDK to use the offline cache docRef.get(source).addOnCompleteListener { task -> if (task.isSuccessful) { // Document found in the offline cache val document = task.result Log.d(TAG, "Cached document data: ${document?.data}") } else { Log.d(TAG, "Cached get failed: ", task.exception) } }
Java
No es compatible con el SDK de Java.
Python
No compatible con el SDK de Python.
C++
DocumentReference doc_ref = db->Collection("cities").Document("SF"); Source source = Source::kCache; doc_ref.Get(source).OnCompletion([](const Future<DocumentSnapshot>& future) { if (future.error() == Error::kErrorOk) { const DocumentSnapshot& document = *future.result(); if (document.exists()) { std::cout << "Cached document id: " << document.id() << '\n'; } else { } } else { std::cout << "Cached get failed: " << future.error_message() << '\n'; } });
Node.js
No compatible con el SDK de Node.js.
Go
No es compatible con el SDK de Go.
PHP
No es compatible con el SDK de PHP.
Unity
No es compatible con el SDK de Unity.
C#
No se admite en el SDK de C #.
Ruby
No es compatible con el SDK de Ruby.
Objetos personalizados
El ejemplo anterior recuperó el contenido del documento en formato de mapa, pero en algunos lenguajes suele ser más conveniente usar un tipo de objeto personalizado. En el ejemplo del artículo Agrega datos, estableciste una clase City
que luego usaste para definir cada ciudad. Puedes convertir el documento nuevamente en un objeto City
de la siguiente manera:
Web
Para usar objetos personalizados, debes definir una función FirestoreDataConverter para tu clase. Por ejemplo:
class City { constructor (name, state, country ) { this.name = name; this.state = state; this.country = country; } toString() { return this.name + ', ' + this.state + ', ' + this.country; } } // Firestore data converter var cityConverter = { toFirestore: function(city) { return { name: city.name, state: city.state, country: city.country }; }, fromFirestore: function(snapshot, options){ const data = snapshot.data(options); return new City(data.name, data.state, data.country); } };Llama al convertidor de datos con tus operaciones de lectura. Después de la conversión, puedes acceder a los métodos de objetos personalizados:
db.collection("cities").doc("LA") .withConverter(cityConverter) .get().then((doc) => { if (doc.exists){ // Convert to City object var city = doc.data(); // Use a City instance method console.log(city.toString()); } else { console.log("No such document!"); }}).catch((error) => { console.log("Error getting document:", error); });
Swift
Para admitir la serialización automática de tipos en Swift, tu tipo debe cumplir con el protocolo de codificación y debes incluir pod 'FirebaseFirestoreSwift'
como dependencia del proyecto.
let docRef = db.collection("cities").document("BJ") docRef.getDocument { (document, error) in // Construct a Result type to encapsulate deserialization errors or // successful deserialization. Note that if there is no error thrown // the value may still be `nil`, indicating a successful deserialization // of a value that does not exist. // // There are thus three cases to handle, which Swift lets us describe // nicely with built-in Result types: // // Result // /\ // Error Optional<City> // /\ // Nil City let result = Result { try document?.data(as: City.self) } switch result { case .success(let city): if let city = city { // A `City` value was successfully initialized from the DocumentSnapshot. print("City: \(city)") } else { // A nil value was successfully initialized from the DocumentSnapshot, // or the DocumentSnapshot was nil. print("Document does not exist") } case .failure(let error): // A `City` value could not be initialized from the DocumentSnapshot. print("Error decoding city: \(error)") } }
Objective-C
En Objective-C, debes hacerlo de forma manual.
FIRDocumentReference *docRef = [[self.db collectionWithPath:@"cities"] documentWithPath:@"BJ"]; [docRef getDocumentWithCompletion:^(FIRDocumentSnapshot *snapshot, NSError *error) { FSTCity *city = [[FSTCity alloc] initWithDictionary:snapshot.data]; if (city != nil) { NSLog(@"City: %@", city); } else { NSLog(@"Document does not exist"); } }];
Java
Importante: Cada clase personalizada debe tener un constructor público que no acepte argumentos. Además, la clase debe incluir un método get público para cada propiedad.
DocumentReference docRef = db.collection("cities").document("BJ"); docRef.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() { @Override public void onSuccess(DocumentSnapshot documentSnapshot) { City city = documentSnapshot.toObject(City.class); } });
Kotlin+KTX
val docRef = db.collection("cities").document("BJ") docRef.get().addOnSuccessListener { documentSnapshot -> val city = documentSnapshot.toObject<City>() }
Java
Cada clase personalizada debe tener un constructor público que no acepte argumentos. Además, la clase debe incluir un captador público para cada propiedad.
DocumentReference docRef = db.collection("cities").document("BJ"); // asynchronously retrieve the document ApiFuture<DocumentSnapshot> future = docRef.get(); // block on response DocumentSnapshot document = future.get(); City city = null; if (document.exists()) { // convert document to POJO city = document.toObject(City.class); System.out.println(city); } else { System.out.println("No such document!"); }
Python
doc_ref = db.collection(u'cities').document(u'BJ') doc = doc_ref.get() city = City.from_dict(doc.to_dict()) print(city)
C++
// This is not yet supported.
Node.js
Node.js usa objetos de JavaScript.
Go
dsnap, err := client.Collection("cities").Doc("BJ").Get(ctx) if err != nil { return nil, err } var c City dsnap.DataTo(&c) fmt.Printf("Document data: %#v\n", c)
PHP
No aplicable para PHP.
Unity
DocumentReference docRef = db.Collection("cities").Document("BJ"); docRef.GetSnapshotAsync().ContinueWith((task) => { var snapshot = task.Result; if (snapshot.Exists) { Debug.Log(String.Format("Document data for {0} document:", snapshot.Id)); City city = snapshot.ConvertTo<City>(); Debug.Log(String.Format("Name: {0}", city.Name)); Debug.Log(String.Format("State: {0}", city.State)); Debug.Log(String.Format("Country: {0}", city.Country)); Debug.Log(String.Format("Capital: {0}", city.Capital)); Debug.Log(String.Format("Population: {0}", city.Population)); } else { Debug.Log(String.Format("Document {0} does not exist!", snapshot.Id)); } });
C#
DocumentReference docRef = db.Collection("cities").Document("BJ"); DocumentSnapshot snapshot = await docRef.GetSnapshotAsync(); if (snapshot.Exists) { Console.WriteLine("Document data for {0} document:", snapshot.Id); City city = snapshot.ConvertTo<City>(); Console.WriteLine("Name: {0}", city.Name); Console.WriteLine("State: {0}", city.State); Console.WriteLine("Country: {0}", city.Country); Console.WriteLine("Capital: {0}", city.Capital); Console.WriteLine("Population: {0}", city.Population); } else { Console.WriteLine("Document {0} does not exist!", snapshot.Id); }
Ruby
No aplicable para Ruby.
Obtén varios documentos de una colección
También puedes recuperar varios documentos con una solicitud a través de una consulta a los documentos de una colección. Por ejemplo, puedes usar where()
para hacer una consulta a fin de buscar todos los documentos que cumplan una condición determinada y, luego, usar get()
para recuperar los resultados:
Web
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); });
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
Según la configuración predeterminada, Cloud Firestore recupera todos los documentos que satisfacen la consulta en orden ascendente por ID de documento, pero puedes ordenar y limitar los datos que se muestran.
Obtén todos los documentos de una colección
Además, para recuperar todos los documentos de una colección, puedes omitir el filtro where()
por completo, como se muestra a continuación:
Web
db.collection("cities").get().then((querySnapshot) => { querySnapshot.forEach((doc) => { // doc.data() is never undefined for query doc snapshots console.log(doc.id, " => ", doc.data()); }); });
Swift
db.collection("cities").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"] 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") .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") .get() .addOnSuccessListener { result -> for (document in result) { Log.d(TAG, "${document.id} => ${document.data}") } } .addOnFailureListener { exception -> Log.d(TAG, "Error getting documents: ", exception) }
Java
//asynchronously retrieve all documents ApiFuture<QuerySnapshot> future = db.collection("cities").get(); // future.get() blocks on response List<QueryDocumentSnapshot> documents = future.get().getDocuments(); for (QueryDocumentSnapshot document : documents) { System.out.println(document.getId() + " => " + document.toObject(City.class)); }
Python
docs = db.collection(u'cities').stream() for doc in docs: print(f'{doc.id} => {doc.to_dict()}')
C++
db->Collection("cities").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.get(); snapshot.forEach(doc => { console.log(doc.id, '=>', doc.data()); });
Go
fmt.Println("All cities:") iter := client.Collection("cities").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'); $documents = $citiesRef->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 allCitiesQuery = db.Collection("cities"); allCitiesQuery.GetSnapshotAsync().ContinueWithOnMainThread(task => { QuerySnapshot allCitiesQuerySnapshot = task.Result; foreach (DocumentSnapshot documentSnapshot in allCitiesQuerySnapshot.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(""); } }); Test
C#
Query allCitiesQuery = db.Collection("cities"); QuerySnapshot allCitiesQuerySnapshot = await allCitiesQuery.GetSnapshotAsync(); foreach (DocumentSnapshot documentSnapshot in allCitiesQuerySnapshot.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 cities_ref.get do |city| puts "#{city.document_id} data: #{city.data}." end
Obtén varios documentos de un grupo de colecciones
Un grupo de colecciones consta de todas las colecciones con el mismo ID. Por ejemplo, si cada documento de tu colección cities
tiene una subcolección llamada landmarks
, todas las subcolecciones landmarks
pertenecerán al mismo grupo de colecciones. Según la configuración predeterminada, las consultas recuperan los resultados de una sola colección de tu base de datos. Usa una consulta de grupos de colecciones para obtener resultados de un grupo de colecciones en lugar de una sola.
Muestra una lista de las subcolecciones de un documento
El método getCollections()
de las bibliotecas cliente del servidor de Cloud Firestore muestra una lista de todas las subcolecciones de una referencia de documento.
No se puede recuperar una lista de colecciones con las bibliotecas cliente web o para dispositivos móviles. Únicamente deberías buscar nombres de colecciones como parte de tareas administrativas en entornos de servidor de confianza. Si necesitas esta función en las bibliotecas cliente web o para dispositivos móviles, te recomendamos volver a estructurar los datos para que sean predecibles los nombres de las subcolecciones.
Web
No está disponible en la biblioteca cliente de la Web.
Swift
No está disponible en la biblioteca cliente de iOS.
Objective-C
No está disponible en la biblioteca cliente de Objective-C.
Java
No está disponible en la biblioteca cliente de Android.
Kotlin+KTX
No está disponible en la biblioteca cliente de Android.
Java
Iterable<CollectionReference> collections = db.collection("cities").document("SF").listCollections(); for (CollectionReference collRef : collections) { System.out.println("Found subcollection with id: " + collRef.getId()); }
Python
collections = db.collection('cities').document('SF').collections() for collection in collections: for doc in collection.stream(): print(f'{doc.id} => {doc.to_dict()}')
C++
No está disponible en la biblioteca cliente de C++.
Node.js
const sfRef = db.collection('cities').doc('SF'); const collections = await sfRef.listCollections(); collections.forEach(collection => { console.log('Found subcollection with id:', collection.id); });
Go
iter := client.Collection("cities").Doc("SF").Collections(ctx) for { collRef, err := iter.Next() if err == iterator.Done { break } if err != nil { return err } fmt.Printf("Found collection with id: %s\n", collRef.ID) }
PHP
$cityRef = $db->collection('cities')->document('SF'); $collections = $cityRef->collections(); foreach ($collections as $collection) { printf('Found subcollection with id: %s' . PHP_EOL, $collection->id()); }
Unity
// This is not yet supported in the Unity SDK.
C#
DocumentReference cityRef = db.Collection("cities").Document("SF"); IAsyncEnumerable<CollectionReference> subcollections = cityRef.ListCollectionsAsync(); IAsyncEnumerator<CollectionReference> subcollectionsEnumerator = subcollections.GetAsyncEnumerator(default); while (await subcollectionsEnumerator.MoveNextAsync()) { CollectionReference subcollectionRef = subcollectionsEnumerator.Current; Console.WriteLine("Found subcollection with ID: {0}", subcollectionRef.Id); }
Ruby
city_ref = firestore.doc "#{collection_path}/SF" city_ref.cols do |col| puts col.collection_id end
Obtén más información sobre los diferentes tipos de consultas.