Cloud Firestore

Cloud Firestore is a NoSQL document database built for automatic scaling, high performance, and ease of application development. While the Cloud Firestore interface has many of the same features as traditional databases, as a NoSQL database it differs from them in the way it describes relationships between data objects.

For more information about Cloud Firestore, read the Cloud Firestore Documentation .

The goal of google-cloud is to provide an API that is comfortable to Rubyists. Authentication is handled by Firestore.new . You can provide the project and credential information to connect to the Cloud Firestore service, or if you are running on Google Cloud Platform (GCP), including Google Compute Engine (GCE), Google Kubernetes Engine (GKE), Google App Engine (GAE), Google Cloud Functions (GCF) and Cloud Run this configuration is taken care of for you. You can read more about the options for connecting in the Authentication Guide .

Adding data

Cloud Firestore stores data in Documents, which are stored in Collections. Cloud Firestore creates collections and documents implicitly the first time you add data to the document. (For more information, see Adding Data to Cloud Firestore .

To create or overwrite a single document, use Client#doc to obtain a document reference. (This does not create a document in Cloud Firestore.) Then, call DocumentReference#set to create the document or overwrite an existing document:

 require 
  
 "google/cloud/firestore" 
 firestore 
  
 = 
  
 Google 
 :: 
 Cloud 
 :: 
 Firestore 
 . 
 new 
 # Get a document reference 
 nyc_ref 
  
 = 
  
 firestore 
 . 
 doc 
  
 "cities/NYC" 
 nyc_ref 
 . 
 set 
 ({ 
  
 name 
 : 
  
 "New York City" 
  
 }) 
  
 # Document created 

When you use this combination of doc and set to create a new document, you must specify an ID for the document. (In the example above, the ID is "NYC".) However, if you do not have a meaningful ID for the document, you may omit the ID from a call to CollectionReference#doc , and Cloud Firestore will auto-generate an ID for you.

 require 
  
 "google/cloud/firestore" 
 firestore 
  
 = 
  
 Google 
 :: 
 Cloud 
 :: 
 Firestore 
 . 
 new 
 # Get a collection reference 
 cities_col 
  
 = 
  
 firestore 
 . 
 col 
  
 "cities" 
 # Get a document reference with data 
 random_ref 
  
 = 
  
 cities_col 
 . 
 doc 
 random_ref 
 . 
 set 
 ({ 
  
 name 
 : 
  
 "New York City" 
  
 }) 
 # The document ID is randomly generated 
 random_ref 
 . 
 document_id 
  
 #=> "RANDOMID123XYZ" 

You can perform both of the operations shown above, auto-generating an ID and creating the document, in a single call to CollectionReference#add .

 require 
  
 "google/cloud/firestore" 
 firestore 
  
 = 
  
 Google 
 :: 
 Cloud 
 :: 
 Firestore 
 . 
 new 
 # Get a collection reference 
 cities_col 
  
 = 
  
 firestore 
 . 
 col 
  
 "cities" 
 # Get a document reference with data 
 random_ref 
  
 = 
  
 cities_col 
 . 
 add 
 ({ 
  
 name 
 : 
  
 "New York City" 
  
 }) 
 # The document ID is randomly generated 
 random_ref 
 . 
 document_id 
  
 #=> "RANDOMID123XYZ" 

You can also use add to create an empty document:

 require 
  
 "google/cloud/firestore" 
 firestore 
  
 = 
  
 Google 
 :: 
 Cloud 
 :: 
 Firestore 
 . 
 new 
 # Get a collection reference 
 cities_col 
  
 = 
  
 firestore 
 . 
 col 
  
 "cities" 
 # Create a document without data 
 random_ref 
  
 = 
  
 cities_col 
 . 
 add 
 # The document ID is randomly generated 
 random_ref 
 . 
 document_id 
  
 #=> "RANDOMID123XYZ" 

Retrieving collection references

Collections are simply named containers for documents. A collection contains documents and nothing else. It can't directly contain raw fields with values, and it can't contain other collections. You do not need to "create" or "delete" collections. After you create the first document in a collection, the collection exists. If you delete all of the documents in a collection, it no longer exists. (For more information, see Cloud Firestore Data Model .)

Use Client#cols to list the root-level collections:

 require 
  
 "google/cloud/firestore" 
 firestore 
  
 = 
  
 Google 
 :: 
 Cloud 
 :: 
 Firestore 
 . 
 new 
 # Get the root collections 
 firestore 
 . 
 cols 
 . 
 each 
  
 do 
  
 | 
 col 
 | 
  
 puts 
  
 col 
 . 
 collection_id 
 end 

Retrieving a reference to a single root-level collection is similar:

 require 
  
 "google/cloud/firestore" 
 firestore 
  
 = 
  
 Google 
 :: 
 Cloud 
 :: 
 Firestore 
 . 
 new 
 # Get the cities collection 
 cities_col 
  
 = 
  
 firestore 
 . 
 col 
  
 "cities" 

To list the collections in a document, first get the document reference, then use DocumentReference#cols :

 require 
  
 "google/cloud/firestore" 
 firestore 
  
 = 
  
 Google 
 :: 
 Cloud 
 :: 
 Firestore 
 . 
 new 
 # Get a document reference 
 nyc_ref 
  
 = 
  
 firestore 
 . 
 doc 
  
 "cities/NYC" 
 nyc_ref 
 . 
 cols 
 . 
 each 
  
 do 
  
 | 
 col 
 | 
  
 puts 
  
 col 
 . 
 collection_id 
 end 

Again, retrieving a reference to a single collection is similar::

 require 
  
 "google/cloud/firestore" 
 firestore 
  
 = 
  
 Google 
 :: 
 Cloud 
 :: 
 Firestore 
 . 
 new 
 # Get a document reference 
 nyc_ref 
  
 = 
  
 firestore 
 . 
 doc 
  
 "cities/NYC" 
 # Get precincts sub-collection 
 precincts_col 
  
 = 
  
 nyc_ref 
 . 
 col 
  
 "precincts" 

Reading data

You can retrieve a snapshot of the data in a single document with DocumentReference#get , which returns an instance of DocumentSnapshot :

 require 
  
 "google/cloud/firestore" 
 firestore 
  
 = 
  
 Google 
 :: 
 Cloud 
 :: 
 Firestore 
 . 
 new 
 # Get a document reference 
 nyc_ref 
  
 = 
  
 firestore 
 . 
 doc 
  
 "cities/NYC" 
 nyc_snap 
  
 = 
  
 nyc_ref 
 . 
 get 
 nyc_snap 
 [ 
 :population 
 ] 
  
 #=> 1000000 

In the example above, DocumentSnapshot#[] is used to access a top-level field. To access nested fields, use FieldPath :

 require 
  
 "google/cloud/firestore" 
 firestore 
  
 = 
  
 Google 
 :: 
 Cloud 
 :: 
 Firestore 
 . 
 new 
 user_snap 
  
 = 
  
 firestore 
 . 
 doc 
 ( 
 "users/frank" 
 ) 
 . 
 get 
 nested_field_path 
  
 = 
  
 firestore 
 . 
 field_path 
  
 :favorites 
 , 
  
 :food 
 user_snap 
 . 
 get 
 ( 
 nested_field_path 
 ) 
  
 #=> "Pizza" 

Or, use Client#get_all to retrieve a list of document snapshots (data):

 require 
  
 "google/cloud/firestore" 
 firestore 
  
 = 
  
 Google 
 :: 
 Cloud 
 :: 
 Firestore 
 . 
 new 
 # Get and print city documents 
 cities 
  
 = 
  
 [ 
 "cities/NYC" 
 , 
  
 "cities/SF" 
 , 
  
 "cities/LA" 
 ] 
 firestore 
 . 
 get_all 
 ( 
 cities 
 ) 
 . 
 each 
  
 do 
  
 | 
 city 
 | 
  
 puts 
  
 " 
 #{ 
 city 
 . 
 document_id 
 } 
 has 
 #{ 
 city 
 [ 
 :population 
 ] 
 } 
 residents." 
 end 

To retrieve all of the document snapshots in a collection, use CollectionReference#get :

 require 
  
 "google/cloud/firestore" 
 firestore 
  
 = 
  
 Google 
 :: 
 Cloud 
 :: 
 Firestore 
 . 
 new 
 # Get a collection reference 
 cities_col 
  
 = 
  
 firestore 
 . 
 col 
  
 "cities" 
 # Get and print all city documents 
 cities_col 
 . 
 get 
  
 do 
  
 | 
 city 
 | 
  
 puts 
  
 " 
 #{ 
 city 
 . 
 document_id 
 } 
 has 
 #{ 
 city 
 [ 
 :population 
 ] 
 } 
 residents." 
 end 

The example above is actually a simple query without filters. Let's look at some other queries for Cloud Firestore.

Querying data

Use Query#where to filter queries on a field:

 require 
  
 "google/cloud/firestore" 
 firestore 
  
 = 
  
 Google 
 :: 
 Cloud 
 :: 
 Firestore 
 . 
 new 
 # Get a collection reference 
 cities_col 
  
 = 
  
 firestore 
 . 
 col 
  
 "cities" 
 # Create a query 
 query 
  
 = 
  
 cities_col 
 . 
 where 
 ( 
 :population 
 , 
  
 : 
> = 
 , 
  
 1000000 
 ) 
 query 
 . 
 get 
  
 do 
  
 | 
 city 
 | 
  
 puts 
  
 " 
 #{ 
 city 
 . 
 document_id 
 } 
 has 
 #{ 
 city 
 [ 
 :population 
 ] 
 } 
 residents." 
 end 

You can order the query results with Query#order :

 require 
  
 "google/cloud/firestore" 
 firestore 
  
 = 
  
 Google 
 :: 
 Cloud 
 :: 
 Firestore 
 . 
 new 
 # Get a collection reference 
 cities_col 
  
 = 
  
 firestore 
 . 
 col 
  
 "cities" 
 # Create a query 
 query 
  
 = 
  
 cities_col 
 . 
 order 
 ( 
 :name 
 , 
  
 :desc 
 ) 
 query 
 . 
 get 
  
 do 
  
 | 
 city 
 | 
  
 puts 
  
 " 
 #{ 
 city 
 . 
 document_id 
 } 
 has 
 #{ 
 city 
 [ 
 :population 
 ] 
 } 
 residents." 
 end 

Query methods may be chained, as in this example using Query#limit and Query#offset to perform pagination:

 require 
  
 "google/cloud/firestore" 
 firestore 
  
 = 
  
 Google 
 :: 
 Cloud 
 :: 
 Firestore 
 . 
 new 
 # Get a collection reference 
 cities_col 
  
 = 
  
 firestore 
 . 
 col 
  
 "cities" 
 # Create a query 
 query 
  
 = 
  
 cities_col 
 . 
 limit 
 ( 
 5 
 ) 
 . 
 offset 
 ( 
 10 
 ) 
 query 
 . 
 get 
  
 do 
  
 | 
 city 
 | 
  
 puts 
  
 " 
 #{ 
 city 
 . 
 document_id 
 } 
 has 
 #{ 
 city 
 [ 
 :population 
 ] 
 } 
 residents." 
 end 

See Managing Indexes in Cloud Firestore to ensure the best performance for your queries.

Updating data

You can use DocumentReference#set to completely overwrite an existing document:

 require 
  
 "google/cloud/firestore" 
 firestore 
  
 = 
  
 Google 
 :: 
 Cloud 
 :: 
 Firestore 
 . 
 new 
 # Get a document reference 
 nyc_ref 
  
 = 
  
 firestore 
 . 
 doc 
  
 "cities/NYC" 
 nyc_ref 
 . 
 set 
 ({ 
  
 name 
 : 
  
 "New York City" 
  
 }) 

Or, to selectively update only the fields appearing in your data argument, set the merge option to true :

 require 
  
 "google/cloud/firestore" 
 firestore 
  
 = 
  
 Google 
 :: 
 Cloud 
 :: 
 Firestore 
 . 
 new 
 # Get a document reference 
 nyc_ref 
  
 = 
  
 firestore 
 . 
 doc 
  
 "cities/NYC" 
 nyc_ref 
 . 
 set 
 ({ 
  
 name 
 : 
  
 "New York City" 
  
 }, 
  
 merge 
 : 
  
 true 
 ) 

Use DocumentReference#update to directly update a deeply-nested field with a Google::Cloud::Firestore::FieldPath :

 require 
  
 "google/cloud/firestore" 
 firestore 
  
 = 
  
 Google 
 :: 
 Cloud 
 :: 
 Firestore 
 . 
 new 
 user_ref 
  
 = 
  
 firestore 
 . 
 doc 
  
 "users/frank" 
 nested_field_path 
  
 = 
  
 firestore 
 . 
 field_path 
  
 :favorites 
 , 
  
 :food 
 user_ref 
 . 
 update 
 ({ 
  
 nested_field_path 
  
 = 
>  
 "Pasta" 
  
 }) 

Listening for changes

You can listen to a document reference or a collection reference/query for changes. The current document snapshot or query results snapshot will be yielded first, and each time the contents change.

You can use DocumentReference#listen to be notified of changes to a single document:

 require 
  
 "google/cloud/firestore" 
 firestore 
  
 = 
  
 Google 
 :: 
 Cloud 
 :: 
 Firestore 
 . 
 new 
 # Get a document reference 
 nyc_ref 
  
 = 
  
 firestore 
 . 
 doc 
  
 "cities/NYC" 
 listener 
  
 = 
  
 nyc_ref 
 . 
 listen 
  
 do 
  
 | 
 snapshot 
 | 
  
 puts 
  
 "The population of 
 #{ 
 snapshot 
 [ 
 :name 
 ] 
 } 
 " 
  
 puts 
  
 "is 
 #{ 
 snapshot 
 [ 
 :population 
 ] 
 } 
 ." 
 end 
 # When ready, stop the listen operation and close the stream. 
 listener 
 . 
 stop 

You can use Query#listen to be notified of changes to any document contained in the query:

 require 
  
 "google/cloud/firestore" 
 firestore 
  
 = 
  
 Google 
 :: 
 Cloud 
 :: 
 Firestore 
 . 
 new 
 # Create a query 
 query 
  
 = 
  
 firestore 
 . 
 col 
 ( 
 :cities 
 ) 
 . 
 order 
 ( 
 :population 
 , 
  
 :desc 
 ) 
 listener 
  
 = 
  
 query 
 . 
 listen 
  
 do 
  
 | 
 snapshot 
 | 
  
 puts 
  
 "The query snapshot has 
 #{ 
 snapshot 
 . 
 docs 
 . 
 count 
 } 
 documents " 
  
 puts 
  
 "and has 
 #{ 
 snapshot 
 . 
 changes 
 . 
 count 
 } 
 changes." 
 end 
 # When ready, stop the listen operation and close the stream. 
 listener 
 . 
 stop 

Using transactions and batched writes

Cloud Firestore supports atomic operations for reading and writing data. In a set of atomic operations, either all of the operations succeed, or none of them are applied. There are two types of atomic operations in Cloud Firestore: A transaction is a set of read and write operations on one or more documents, while a batched write is a set of only write operations on one or more documents. (For more information, see Transactions and Batched Writes .

Transactions

A transaction consists of any number of read operations followed by any number of write operations. (Read operations must always come before write operations.) In the case of a concurrent update by another client, Cloud Firestore runs the entire transaction again. Therefore, transaction blocks should be idempotent and should not not directly modify application state.

 require 
  
 "google/cloud/firestore" 
 firestore 
  
 = 
  
 Google 
 :: 
 Cloud 
 :: 
 Firestore 
 . 
 new 
 city 
  
 = 
  
 firestore 
 . 
 col 
 ( 
 "cities" 
 ) 
 . 
 doc 
 ( 
 "SF" 
 ) 
 city 
 . 
 set 
 ({ 
  
 name 
 : 
  
 "San Francisco" 
 , 
  
 state 
 : 
  
 "CA" 
 , 
  
 country 
 : 
  
 "USA" 
 , 
  
 capital 
 : 
  
 false 
 , 
  
 population 
 : 
  
 860000 
  
 }) 
 firestore 
 . 
 transaction 
  
 do 
  
 | 
 tx 
 | 
  
 new_population 
  
 = 
  
 tx 
 . 
 get 
 ( 
 city 
 ) 
 . 
 data 
 [ 
 :population 
 ] 
  
 + 
  
 1 
  
 tx 
 . 
 update 
 ( 
 city 
 , 
  
 { 
  
 population 
 : 
  
 new_population 
  
 }) 
 end 

Batched writes

If you do not need to read any documents in your operation set, you can execute multiple write operations as a single batch. A batch of writes completes atomically and can write to multiple documents. Batched writes are also useful for migrating large data sets to Cloud Firestore.

 require 
  
 "google/cloud/firestore" 
 firestore 
  
 = 
  
 Google 
 :: 
 Cloud 
 :: 
 Firestore 
 . 
 new 
 firestore 
 . 
 batch 
  
 do 
  
 | 
 b 
 | 
  
 # Set the data for NYC 
  
 b 
 . 
 set 
 ( 
 "cities/NYC" 
 , 
  
 { 
  
 name 
 : 
  
 "New York City" 
  
 }) 
  
 # Update the population for SF 
  
 b 
 . 
 update 
 ( 
 "cities/SF" 
 , 
  
 { 
  
 population 
 : 
  
 1000000 
  
 }) 
  
 # Delete LA 
  
 b 
 . 
 delete 
 ( 
 "cities/LA" 
 ) 
 end 

Deleting data

Use DocumentReference#delete to delete a document from Cloud Firestore:

 require 
  
 "google/cloud/firestore" 
 firestore 
  
 = 
  
 Google 
 :: 
 Cloud 
 :: 
 Firestore 
 . 
 new 
 # Get a document reference 
 nyc_ref 
  
 = 
  
 firestore 
 . 
 doc 
  
 "cities/NYC" 
 nyc_ref 
 . 
 delete 

To delete specific fields from a document, use the Client.field_delete method when you update a document:

 require 
  
 "google/cloud/firestore" 
 firestore 
  
 = 
  
 Google 
 :: 
 Cloud 
 :: 
 Firestore 
 . 
 new 
 # Get a document reference 
 nyc_ref 
  
 = 
  
 firestore 
 . 
 doc 
  
 "cities/NYC" 
 nyc_ref 
 . 
 update 
 ({ 
  
 name 
 : 
  
 "New York City" 
 , 
  
 trash 
 : 
  
 firestore 
 . 
 field_delete 
  
 }) 

To delete an entire collection or sub-collection in Cloud Firestore, retrieve all the documents within the collection or sub-collection and delete them. If you have larger collections, you may want to delete the documents in smaller batches to avoid out-of-memory errors. Repeat the process until you've deleted the entire collection or sub-collection.

Additional information

Google Firestore can be configured to use gRPC's logging. To learn more, see the Logging guide .

Design a Mobile Site
View Site in Mobile | Classic
Share by: