google-cloud-firestore 2.6.0 → 2.10.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -50,15 +50,18 @@ module Google
50
50
  end
51
51
 
52
52
  def fields_to_hash fields, client
53
- Hash[fields.map do |key, value|
54
- [key.to_sym, value_to_raw(value, client)]
55
- end]
53
+ # Google::Protobuf::Map#to_h ignores the given block, unlike Hash#to_h
54
+ # rubocop:disable Style/MapToHash
55
+ fields
56
+ .map { |key, value| [key.to_sym, value_to_raw(value, client)] }
57
+ .to_h
58
+ # rubocop:enable Style/MapToHash
56
59
  end
57
60
 
58
61
  def hash_to_fields hash
59
- Hash[hash.map do |key, value|
62
+ hash.to_h do |key, value|
60
63
  [String(key), raw_to_value(value)]
61
- end]
64
+ end
62
65
  end
63
66
 
64
67
  def value_to_raw value, client
@@ -304,7 +307,7 @@ module Google
304
307
  field_paths = new_data_pairs.map(&:first)
305
308
 
306
309
  delete_paths.map!(&:first)
307
- root_field_paths_and_values = Hash[root_field_paths_and_values]
310
+ root_field_paths_and_values = root_field_paths_and_values.to_h
308
311
 
309
312
  data, nested_deletes = remove_field_value_from data, :delete
310
313
  raise ArgumentError, "DELETE cannot be nested" if nested_deletes.any?
@@ -425,7 +428,7 @@ module Google
425
428
  end
426
429
 
427
430
  # return new data hash and field path/values hash
428
- [Hash[new_pairs.compact], Hash[paths]]
431
+ [new_pairs.compact.to_h, paths.to_h]
429
432
  end
430
433
 
431
434
  def identify_leaf_nodes hash
@@ -495,7 +498,6 @@ module Google
495
498
  dup_hash = dup_hash[field]
496
499
  end
497
500
  prev_hash[last_field] = dup_hash
498
- prev_hash.delete_if { |_k, v| v.nil? }
499
501
  ret_hash
500
502
  end
501
503
 
@@ -86,8 +86,9 @@ module Google
86
86
  def next
87
87
  return nil unless next?
88
88
  ensure_client!
89
- grpc = @client.service.list_documents @parent, @collection_id, token: token, max: @max
90
- self.class.from_grpc grpc, @client, @parent, @collection_id, @max
89
+ grpc = @client.service.list_documents @parent, @collection_id, token: token, max: @max, \
90
+ read_time: @read_time
91
+ self.class.from_grpc grpc, @client, @parent, @collection_id, @max, read_time: @read_time
91
92
  end
92
93
 
93
94
  ##
@@ -162,7 +163,7 @@ module Google
162
163
  ##
163
164
  # @private New DocumentReference::List from a
164
165
  # Google::Cloud::Firestore::V1::ListDocumentsResponse object.
165
- def self.from_grpc grpc, client, parent, collection_id, max = nil
166
+ def self.from_grpc grpc, client, parent, collection_id, max = nil, read_time: nil
166
167
  documents = List.new(Array(grpc.documents).map do |document|
167
168
  DocumentReference.from_path document.name, client
168
169
  end)
@@ -173,6 +174,7 @@ module Google
173
174
  documents.instance_variable_set :@token, token
174
175
  documents.instance_variable_set :@client, client
175
176
  documents.instance_variable_set :@max, max
177
+ documents.instance_variable_set :@read_time, read_time
176
178
  documents
177
179
  end
178
180
 
@@ -73,6 +73,9 @@ module Google
73
73
  ##
74
74
  # Retrieves an enumerator for the collections nested under the document snapshot.
75
75
  #
76
+ # @param [Time] read_time Reads documents as they were at the given time.
77
+ # This may not be older than 270 seconds. Optional
78
+ #
76
79
  # @yield [collections] The block for accessing the collections.
77
80
  # @yieldparam [CollectionReference] collection A collection reference object.
78
81
  #
@@ -91,10 +94,24 @@ module Google
91
94
  # puts col.collection_id
92
95
  # end
93
96
  #
94
- def cols &block
97
+ # @example Get collection with read time
98
+ # require "google/cloud/firestore"
99
+ #
100
+ # firestore = Google::Cloud::Firestore.new
101
+ #
102
+ # read_time = Time.now
103
+ #
104
+ # # Get a document reference
105
+ # nyc_ref = firestore.doc "cities/NYC"
106
+ #
107
+ # nyc_ref.cols(read_time: read_time).each do |col|
108
+ # puts col.collection_id
109
+ # end
110
+ #
111
+ def cols read_time: nil, &block
95
112
  ensure_service!
96
- grpc = service.list_collections path
97
- cols_enum = CollectionReferenceList.from_grpc(grpc, client, path).all
113
+ grpc = service.list_collections path, read_time: read_time
114
+ cols_enum = CollectionReferenceList.from_grpc(grpc, client, path, read_time: read_time).all
98
115
  cols_enum.each(&block) if block_given?
99
116
  cols_enum
100
117
  end
@@ -209,19 +209,15 @@ module Google
209
209
 
210
210
  protected
211
211
 
212
- START_FIELD_PATH_CHARS = /\A[a-zA-Z_]/.freeze
213
212
  INVALID_FIELD_PATH_CHARS = %r{[~*/\[\]]}.freeze
213
+ SIMPLE_FIELD_PATH_CHARS = /\A[_a-zA-Z][_a-zA-Z0-9]*\Z/.freeze
214
214
 
215
215
  def escape_field_for_path field
216
216
  field = String field
217
217
 
218
- if INVALID_FIELD_PATH_CHARS.match(field) ||
219
- field["."] || field["`"] || field["\\"]
220
- escaped_field = field.gsub(/[`\\]/, "`" => "\\\`", "\\" => "\\\\")
221
- return "`#{escaped_field}`"
222
- end
218
+ return field if SIMPLE_FIELD_PATH_CHARS.match field
223
219
 
224
- return field if START_FIELD_PATH_CHARS.match field
220
+ field = field.gsub(/[`\\]/, "`" => "\\`", "\\" => "\\\\")
225
221
 
226
222
  "`#{field}`"
227
223
  end
@@ -17,6 +17,7 @@ require "google/cloud/firestore/v1"
17
17
  require "google/cloud/firestore/document_snapshot"
18
18
  require "google/cloud/firestore/query_listener"
19
19
  require "google/cloud/firestore/convert"
20
+ require "google/cloud/firestore/aggregate_query"
20
21
  require "json"
21
22
 
22
23
  module Google
@@ -903,6 +904,9 @@ module Google
903
904
  ##
904
905
  # Retrieves document snapshots for the query.
905
906
  #
907
+ # @param [Time] read_time Reads documents as they were at the given time.
908
+ # This may not be older than 270 seconds. Optional
909
+ #
906
910
  # @yield [documents] The block for accessing the document snapshots.
907
911
  # @yieldparam [DocumentSnapshot] document A document snapshot.
908
912
  #
@@ -923,12 +927,29 @@ module Google
923
927
  # puts "#{city.document_id} has #{city[:population]} residents."
924
928
  # end
925
929
  #
926
- def get
930
+ # @example Get query with read time
931
+ # require "google/cloud/firestore"
932
+ #
933
+ # firestore = Google::Cloud::Firestore.new
934
+ #
935
+ # # Get a collection reference
936
+ # cities_col = firestore.col "cities"
937
+ #
938
+ # # Create a query
939
+ # query = cities_col.select(:population)
940
+ #
941
+ # read_time = Time.now
942
+ #
943
+ # query.get(read_time: read_time) do |city|
944
+ # puts "#{city.document_id} has #{city[:population]} residents."
945
+ # end
946
+ #
947
+ def get read_time: nil
927
948
  ensure_service!
928
949
 
929
- return enum_for :get unless block_given?
950
+ return enum_for :get, read_time: read_time unless block_given?
930
951
 
931
- results = service.run_query parent_path, @query
952
+ results = service.run_query parent_path, @query, read_time: read_time
932
953
 
933
954
  # Reverse the results for Query#limit_to_last queries since that method reversed the order_by directions.
934
955
  results = results.to_a.reverse if limit_type == :last
@@ -940,6 +961,26 @@ module Google
940
961
  end
941
962
  alias run get
942
963
 
964
+ ##
965
+ # Creates an AggregateQuery object for the query.
966
+ #
967
+ # @return [AggregateQuery] New empty aggregate query.
968
+ #
969
+ # @example
970
+ # require "google/cloud/firestore"
971
+ #
972
+ # firestore = Google::Cloud::Firestore.new
973
+ #
974
+ # # Get a collection reference
975
+ # query = firestore.col "cities"
976
+ #
977
+ # # Create an aggregate query
978
+ # aggregate_query = query.aggregate_query
979
+ #
980
+ def aggregate_query
981
+ AggregateQuery.new query, parent_path, client
982
+ end
983
+
943
984
  ##
944
985
  # Listen to this query for changes.
945
986
  #
@@ -30,14 +30,16 @@ module Google
30
30
  attr_accessor :credentials
31
31
  attr_accessor :timeout
32
32
  attr_accessor :host
33
+ attr_accessor :database
33
34
 
34
35
  ##
35
36
  # Creates a new Service instance.
36
- def initialize project, credentials, host: nil, timeout: nil
37
+ def initialize project, credentials, host: nil, timeout: nil, database: nil
37
38
  @project = project
38
39
  @credentials = credentials
39
40
  @host = host
40
41
  @timeout = timeout
42
+ @database = database
41
43
  end
42
44
 
43
45
  def firestore
@@ -48,11 +50,11 @@ module Google
48
50
  config.endpoint = host if host
49
51
  config.lib_name = "gccl"
50
52
  config.lib_version = Google::Cloud::Firestore::VERSION
51
- config.metadata = { "google-cloud-resource-prefix": "projects/#{@project}" }
53
+ config.metadata = { "google-cloud-resource-prefix": "projects/#{@project}/databases/#{@database}" }
52
54
  end
53
55
  end
54
56
 
55
- def get_documents document_paths, mask: nil, transaction: nil
57
+ def get_documents document_paths, mask: nil, transaction: nil, read_time: nil
56
58
  batch_get_req = {
57
59
  database: database_path,
58
60
  documents: document_paths,
@@ -63,7 +65,9 @@ module Google
63
65
  elsif transaction
64
66
  batch_get_req[:new_transaction] = transaction
65
67
  end
66
-
68
+ if read_time
69
+ batch_get_req[:read_time] = read_time_to_timestamp(read_time)
70
+ end
67
71
  firestore.batch_get_documents batch_get_req, call_options(parent: database_path)
68
72
  end
69
73
 
@@ -74,23 +78,25 @@ module Google
74
78
  # the showMissing flag to true to support full document traversal. If
75
79
  # there are too many documents, recommendation will be not to call this
76
80
  # method.
77
- def list_documents parent, collection_id, token: nil, max: nil
81
+ def list_documents parent, collection_id, token: nil, max: nil, read_time: nil
78
82
  mask = { field_paths: [] }
79
- paged_enum = firestore.list_documents parent: parent,
83
+ paged_enum = firestore.list_documents parent: parent,
80
84
  collection_id: collection_id,
81
- page_size: max,
82
- page_token: token,
83
- mask: mask,
84
- show_missing: true
85
+ page_size: max,
86
+ page_token: token,
87
+ mask: mask,
88
+ show_missing: true,
89
+ read_time: read_time_to_timestamp(read_time)
85
90
  paged_enum.response
86
91
  end
87
92
 
88
- def list_collections parent, token: nil, max: nil
93
+ def list_collections parent, token: nil, max: nil, read_time: nil
89
94
  firestore.list_collection_ids(
90
95
  {
91
- parent: parent,
92
- page_size: max,
93
- page_token: token
96
+ parent: parent,
97
+ page_size: max,
98
+ page_token: token,
99
+ read_time: read_time_to_timestamp(read_time)
94
100
  },
95
101
  call_options(parent: database_path)
96
102
  )
@@ -98,19 +104,20 @@ module Google
98
104
 
99
105
  ##
100
106
  # Returns Google::Cloud::Firestore::V1::PartitionQueryResponse
101
- def partition_query parent, query_grpc, partition_count, token: nil, max: nil
107
+ def partition_query parent, query_grpc, partition_count, token: nil, max: nil, read_time: nil
102
108
  request = Google::Cloud::Firestore::V1::PartitionQueryRequest.new(
103
109
  parent: parent,
104
110
  structured_query: query_grpc,
105
111
  partition_count: partition_count,
106
112
  page_token: token,
107
- page_size: max
113
+ page_size: max,
114
+ read_time: read_time_to_timestamp(read_time)
108
115
  )
109
116
  paged_enum = firestore.partition_query request
110
117
  paged_enum.response
111
118
  end
112
119
 
113
- def run_query path, query_grpc, transaction: nil
120
+ def run_query path, query_grpc, transaction: nil, read_time: nil
114
121
  run_query_req = {
115
122
  parent: path,
116
123
  structured_query: query_grpc
@@ -120,10 +127,28 @@ module Google
120
127
  elsif transaction
121
128
  run_query_req[:new_transaction] = transaction
122
129
  end
130
+ if read_time
131
+ run_query_req[:read_time] = read_time_to_timestamp(read_time)
132
+ end
123
133
 
124
134
  firestore.run_query run_query_req, call_options(parent: database_path)
125
135
  end
126
136
 
137
+ ##
138
+ # Returns Google::Cloud::Firestore::V1::RunAggregationQueryResponse
139
+ def run_aggregate_query parent, structured_aggregation_query, transaction: nil
140
+ request = Google::Cloud::Firestore::V1::RunAggregationQueryRequest.new(
141
+ parent: parent,
142
+ structured_aggregation_query: structured_aggregation_query
143
+ )
144
+ if transaction.is_a? String
145
+ request.transaction = transaction
146
+ elsif transaction
147
+ request.new_transaction = transaction
148
+ end
149
+ firestore.run_aggregation_query request
150
+ end
151
+
127
152
  def listen enum
128
153
  firestore.listen enum, call_options(parent: database_path)
129
154
  end
@@ -158,18 +183,29 @@ module Google
158
183
  )
159
184
  end
160
185
 
161
- def database_path project_id: project, database_id: "(default)"
186
+ def database_path project_id: project, database_id: database
162
187
  # Originally used V1::FirestoreClient.database_root_path until it was removed in #5405.
163
188
  "projects/#{project_id}/databases/#{database_id}"
164
189
  end
165
190
 
166
- def documents_path project_id: project, database_id: "(default)"
191
+ def documents_path project_id: project, database_id: database
167
192
  # Originally used V1::FirestoreClient.document_root_path until it was removed in #5405.
168
193
  "projects/#{project_id}/databases/#{database_id}/documents"
169
194
  end
170
195
 
171
196
  def inspect
172
- "#{self.class}(#{@project})"
197
+ "#{self.class}(#{@project})(#{@database})"
198
+ end
199
+
200
+ def read_time_to_timestamp read_time
201
+ return nil if read_time.nil?
202
+
203
+ raise TypeError, "read_time is expected to be a Time object" unless read_time.is_a? Time
204
+
205
+ Google::Protobuf::Timestamp.new(
206
+ seconds: read_time.to_i,
207
+ nanos: read_time.usec * 1000
208
+ )
173
209
  end
174
210
 
175
211
  protected
@@ -189,7 +225,7 @@ module Google
189
225
  def document_mask mask
190
226
  return nil if mask.nil?
191
227
 
192
- mask = Array(mask).map(&:to_s).reject(&:nil?).reject(&:empty?)
228
+ mask = Array(mask).map(&:to_s).reject(&:empty?)
193
229
  return nil if mask.empty?
194
230
 
195
231
  Google::Cloud::Firestore::V1::DocumentMask.new field_paths: mask
@@ -269,6 +269,51 @@ module Google
269
269
  end
270
270
  alias run get
271
271
 
272
+ ##
273
+ # Retrieves aggregate query snapshots for the given value. Valid values can be
274
+ # a string representing either a document or a collection of documents,
275
+ # a document reference object, a collection reference object, or a query
276
+ # to be run.
277
+ #
278
+ # @param [AggregateQuery] aggregate_query
279
+ # An AggregateQuery object
280
+ #
281
+ # @yield [documents] The block for accessing the aggregate query snapshot.
282
+ # @yieldparam [AggregateQuerySnapshot] aggregate_snapshot An aggregate query snapshot.
283
+ #
284
+ # @example
285
+ # require "google/cloud/firestore"
286
+ #
287
+ # firestore = Google::Cloud::Firestore.new
288
+ #
289
+ # query = firestore.col "cities"
290
+ #
291
+ # # Create an aggregate query
292
+ # aq = query.aggregate_query
293
+ # .add_count
294
+ #
295
+ # firestore.transaction do |tx|
296
+ # tx.get_aggregate aq do |aggregate_snapshot|
297
+ # puts aggregate_snapshot.get
298
+ # end
299
+ # end
300
+ #
301
+ def get_aggregate aggregate_query
302
+ ensure_not_closed!
303
+ ensure_service!
304
+
305
+ return enum_for :get_aggregate, aggregate_query unless block_given?
306
+
307
+ results = service.run_aggregate_query aggregate_query.parent_path,
308
+ aggregate_query.structured_aggregation_query,
309
+ transaction: transaction_or_create
310
+ results.each do |result|
311
+ extract_transaction_from_result! result
312
+ next if result.result.nil?
313
+ yield AggregateQuerySnapshot.from_run_aggregate_query_response result
314
+ end
315
+ end
316
+
272
317
  # @!endgroup
273
318
 
274
319
  # @!group Modifications
@@ -643,10 +688,12 @@ module Google
643
688
 
644
689
  ##
645
690
  # @private New Transaction reference object from a path.
646
- def self.from_client client, previous_transaction: nil
691
+ def self.from_client client, previous_transaction: nil, read_time: nil, read_only: nil
647
692
  new.tap do |s|
648
693
  s.instance_variable_set :@client, client
649
694
  s.instance_variable_set :@previous_transaction, previous_transaction
695
+ s.instance_variable_set :@read_time, read_time
696
+ s.instance_variable_set :@read_only, read_only
650
697
  end
651
698
  end
652
699
 
@@ -699,6 +746,10 @@ module Google
699
746
  ##
700
747
  # @private
701
748
  def transaction_opt
749
+ read_only = \
750
+ Google::Cloud::Firestore::V1::TransactionOptions::ReadOnly.new \
751
+ read_time: service.read_time_to_timestamp(@read_time)
752
+
702
753
  read_write = \
703
754
  Google::Cloud::Firestore::V1::TransactionOptions::ReadWrite.new
704
755
 
@@ -707,9 +758,11 @@ module Google
707
758
  @previous_transaction = nil
708
759
  end
709
760
 
710
- Google::Cloud::Firestore::V1::TransactionOptions.new(
711
- read_write: read_write
712
- )
761
+ if @read_only
762
+ Google::Cloud::Firestore::V1::TransactionOptions.new read_only: read_only
763
+ else
764
+ Google::Cloud::Firestore::V1::TransactionOptions.new read_write: read_write
765
+ end
713
766
  end
714
767
 
715
768
  ##
@@ -16,7 +16,7 @@
16
16
  module Google
17
17
  module Cloud
18
18
  module Firestore
19
- VERSION = "2.6.0".freeze
19
+ VERSION = "2.10.0".freeze
20
20
  end
21
21
  end
22
22
  end
@@ -134,7 +134,7 @@ module Google
134
134
  end
135
135
 
136
136
  def order_for docs
137
- Hash[docs.map { |doc| [doc.path, doc.updated_at] }]
137
+ docs.to_h { |doc| [doc.path, doc.updated_at] }
138
138
  end
139
139
 
140
140
  def current_order
@@ -59,6 +59,8 @@ module Google
59
59
  # If the param is nil, uses the default endpoint.
60
60
  # @param [String] emulator_host Firestore emulator host. Optional.
61
61
  # If the param is nil, uses the value of the `emulator_host` config.
62
+ # @param [String] database_id Identifier for a Firestore database. If not
63
+ # present, the default database of the project is used.
62
64
  # @param [String] project Alias for the `project_id` argument. Deprecated.
63
65
  # @param [String] keyfile Alias for the `credentials` argument.
64
66
  # Deprecated.
@@ -76,19 +78,22 @@ module Google
76
78
  timeout: nil,
77
79
  endpoint: nil,
78
80
  emulator_host: nil,
81
+ database_id: nil,
79
82
  project: nil,
80
83
  keyfile: nil
81
- project_id ||= (project || default_project_id)
82
- scope ||= configure.scope
83
- timeout ||= configure.timeout
84
- endpoint ||= configure.endpoint
84
+ project_id ||= (project || default_project_id)
85
+ scope ||= configure.scope
86
+ timeout ||= configure.timeout
87
+ endpoint ||= configure.endpoint
85
88
  emulator_host ||= configure.emulator_host
89
+ database_id ||= configure.database_id
86
90
 
87
91
  if emulator_host
88
92
  project_id = project_id.to_s
89
93
  raise ArgumentError, "project_id is missing" if project_id.empty?
90
94
 
91
- service = Firestore::Service.new project_id, :this_channel_is_insecure, host: emulator_host, timeout: timeout
95
+ service = Firestore::Service.new project_id, :this_channel_is_insecure, host: emulator_host,
96
+ timeout: timeout, database: database_id
92
97
  return Firestore::Client.new service
93
98
  end
94
99
 
@@ -103,7 +108,8 @@ module Google
103
108
  project_id = project_id.to_s
104
109
  raise ArgumentError, "project_id is missing" if project_id.empty?
105
110
 
106
- service = Firestore::Service.new project_id, credentials, host: endpoint, timeout: timeout
111
+ service = Firestore::Service.new project_id, credentials, host: endpoint,
112
+ timeout: timeout, database: database_id
107
113
  Firestore::Client.new service
108
114
  end
109
115
 
@@ -122,6 +128,8 @@ module Google
122
128
  # parameter `keyfile` is considered deprecated, but may also be used.)
123
129
  # * `scope` - (String, Array<String>) The OAuth 2.0 scopes controlling
124
130
  # the set of resources and operations that the connection can access.
131
+ # * `quota_project` - (String) The project ID for a project that can be
132
+ # used by client libraries for quota and billing purposes.
125
133
  # * `timeout` - (Integer) Default timeout to use in requests.
126
134
  # * `endpoint` - (String) Override of the endpoint host name, or `nil`
127
135
  # to use the default endpoint.
@@ -42,6 +42,8 @@ module Google
42
42
  #
43
43
  # * `https://www.googleapis.com/auth/datastore`
44
44
  # @param [Integer] timeout Default timeout to use in requests. Optional.
45
+ # @param [String] database_id Identifier for a Firestore database. If not
46
+ # present, the default database of the project is used.
45
47
  #
46
48
  # @return [Google::Cloud::Firestore::Client]
47
49
  #
@@ -58,8 +60,15 @@ module Google
58
60
  # platform_scope = "https://www.googleapis.com/auth/cloud-platform"
59
61
  # firestore = gcloud.firestore scope: platform_scope
60
62
  #
61
- def firestore scope: nil, timeout: nil
62
- Google::Cloud.firestore @project, @keyfile, scope: scope, timeout: (timeout || @timeout)
63
+ # @example The default database can be overridden with the `database_id` option:
64
+ # require "google/cloud"
65
+ #
66
+ # gcloud = Google::Cloud.new
67
+ # database_id = "my-todo-database"
68
+ # firestore = gcloud.firestore database_id: database_id
69
+ #
70
+ def firestore scope: nil, timeout: nil, database_id: nil
71
+ Google::Cloud.firestore @project, @keyfile, scope: scope, timeout: (timeout || @timeout), database_id: database_id
63
72
  end
64
73
 
65
74
  ##
@@ -83,6 +92,8 @@ module Google
83
92
  #
84
93
  # * `https://www.googleapis.com/auth/datastore`
85
94
  # @param [Integer] timeout Default timeout to use in requests. Optional.
95
+ # @param [String] database_id Identifier for a Firestore database. If not
96
+ # present, the default database of the project is used.
86
97
  #
87
98
  # @return [Google::Cloud::Firestore::Client]
88
99
  #
@@ -91,12 +102,13 @@ module Google
91
102
  #
92
103
  # firestore = Google::Cloud.firestore
93
104
  #
94
- def self.firestore project_id = nil, credentials = nil, scope: nil, timeout: nil
105
+ def self.firestore project_id = nil, credentials = nil, scope: nil, timeout: nil, database_id: nil
95
106
  require "google/cloud/firestore"
96
- Google::Cloud::Firestore.new project_id: project_id,
107
+ Google::Cloud::Firestore.new project_id: project_id,
97
108
  credentials: credentials,
98
- scope: scope,
99
- timeout: timeout
109
+ scope: scope,
110
+ timeout: timeout,
111
+ database_id: database_id
100
112
  end
101
113
  end
102
114
  end
@@ -116,8 +128,7 @@ Google::Cloud.configure.add_config! :firestore do |config|
116
128
  ENV["FIRESTORE_EMULATOR_HOST"]
117
129
  end
118
130
  default_scopes = [
119
- "https://www.googleapis.com/auth/cloud-platform",
120
- "https://www.googleapis.com/auth/datastore"
131
+ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/datastore"
121
132
  ]
122
133
 
123
134
  config.add_field! :project_id, default_project, match: String, allow_nil: true
@@ -129,4 +140,5 @@ Google::Cloud.configure.add_config! :firestore do |config|
129
140
  config.add_field! :timeout, nil, match: Integer
130
141
  config.add_field! :emulator_host, default_emulator, match: String, allow_nil: true
131
142
  config.add_field! :endpoint, "firestore.googleapis.com", match: String
143
+ config.add_field! :database_id, "(default)", match: String
132
144
  end