Class: Firestore

Inherits:
Object
  • Object
show all
Defined in:
lib/ons-firestore/firestore.rb

Overview

Class to manage access to Firestore.

Constant Summary collapse

DATE_TIME_FORMAT =

Format to use for the timestamp of the updated key within the Firestore document.

'%A %d %b %Y %H:%M:%S UTC'

Instance Method Summary collapse

Constructor Details

#initialize(project_id) ⇒ Firestore

Constructor that initialises the Firestore client.

Parameters:

  • project_id (String)

    the ID of the GCP project containing the Firestore database

Raises:

  • (ArgumentError)

    if project_id is nil



16
17
18
19
20
21
# File 'lib/ons-firestore/firestore.rb', line 16

def initialize(project_id)
  raise ArgumentError.new('project_id cannot be nil') if project_id.nil?

  Google::Cloud::Firestore.configure { |config| config.project_id = project_id }
  @client = Google::Cloud::Firestore.new
end

Instance Method Details

#all_documents(collection_name) ⇒ Enumerator

Returns all Firestore documents within a collection.

Parameters:

  • collection_name (String)

    the name of the Firestore collection containing the documents

Returns:

  • (Enumerator)

    list of documents within the collection

Raises:

  • (ArgumentError)

    if collection_name is nil



28
29
30
31
32
# File 'lib/ons-firestore/firestore.rb', line 28

def all_documents(collection_name)
  raise ArgumentError.new('collection_name cannot be nil') if collection_name.nil?

  @client.col(collection_name).list_documents.all
end

#document_reference(collection_name, document_name) ⇒ Google::Cloud::Firestore::DocumentReference

Returns a reference to a Firestore document.

Parameters:

  • collection_name (String)

    the name of the Firestore collection containing the document

  • document_name (String)

    the name of the Firestore document

Returns:

  • (Google::Cloud::Firestore::DocumentReference)

    reference to the document

Raises:

  • (ArgumentError)

    if collection_name or document_name are nil



40
41
42
43
44
45
# File 'lib/ons-firestore/firestore.rb', line 40

def document_reference(collection_name, document_name)
  raise ArgumentError.new('collection_name cannot be nil') if collection_name.nil?
  raise ArgumentError.new('document_name cannot be nil') if document_name.nil?

  @client.col(collection_name).doc(document_name)
end

#document_updated(collection_name, document_name) ⇒ Object

Reads the updated key within a Firestore document.

Parameters:

  • collection_name (String)

    the name of the Firestore collection containing the document

  • document_name (String)

    the name of the Firestore document

Returns:

  • (Object)

    document updated timestamp

Raises:

  • (ArgumentError)

    if collection_name or document_name are nil

  • (FirestoreError)

    if the updated key isn’t present within the Firestore document



54
55
56
57
58
59
60
61
62
63
# File 'lib/ons-firestore/firestore.rb', line 54

def document_updated(collection_name, document_name)
  raise ArgumentError.new('collection_name cannot be nil') if collection_name.nil?
  raise ArgumentError.new('document_name cannot be nil') if document_name.nil?

  document = @client.col(collection_name).doc(document_name)
  snapshot = document.get
  raise FirestoreError, 'updated key is missing' if snapshot[:updated].nil?

  snapshot[:updated]
end

#read_document(collection_name, document_name) ⇒ Object

Reads the data key within a Firestore document.

Parameters:

  • collection_name (String)

    the name of the Firestore collection containing the document

  • document_name (String)

    the name of the Firestore document

Returns:

  • (Object)

    document data

Raises:

  • (ArgumentError)

    if collection_name or document_name are nil

  • (FirestoreError)

    if the data key isn’t present within the Firestore document



72
73
74
75
76
77
78
79
80
81
# File 'lib/ons-firestore/firestore.rb', line 72

def read_document(collection_name, document_name)
  raise ArgumentError.new('collection_name cannot be nil') if collection_name.nil?
  raise ArgumentError.new('document_name cannot be nil') if document_name.nil?

  document = @client.col(collection_name).doc(document_name)
  snapshot = document.get
  raise FirestoreError, 'data key is missing' if snapshot.data.nil?

  snapshot[:data]
end

#save_document(collection_name, document_name, data) ⇒ Object

Saves a Firestore document, overwriting any existing document with the same name.

The passed data are saved under a data key within the document. A timestamp at which the operation occurred is saved under the updated key within the document.

Parameters:

  • collection_name (String)

    the name of the Firestore collection containing the document

  • document_name (String)

    the name of the Firestore document

  • data (Object)

    data to save to the Firestore document

Raises:

  • (ArgumentError)

    if collection_name or document_name are nil

  • (FirestoreError)

    if an error occurred whilst saving the document



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/ons-firestore/firestore.rb', line 93

def save_document(collection_name, document_name, data)
  raise ArgumentError.new('collection_name cannot be nil') if collection_name.nil?
  raise ArgumentError.new('document_name cannot be nil') if document_name.nil?

  document = @client.col(collection_name).doc(document_name)
  if data.is_a?(Array)
    hash_data = []
    data.each { |element| element.respond_to?(:to_h) ? hash_data << element.to_h : hash_data << element }
  end

  if data.is_a?(Hash)
    hash_data = {}
    data.each do |key, value|
      hash_data[key] = value.class.method_defined?(:to_h) ? value.map(&:to_h) : value
    end
  end

  begin
    document.set({ data: hash_data, updated: Time.now.strftime(DATE_TIME_FORMAT) })
  rescue StandardError => e
    raise FirestoreError, "Failed to save Firestore document #{document_name} in collection #{collection_name}: #{e.message}"
  end
end