Flame is a data model and query library for Firestore.
Firestore is a fully managed, internet scale document database offered by Google. Flame was designed to improve clarity and accuracy of Firestore related data model and query code.
Among other features, Flame makes it easy to define models, write queries and transactions, and page data with cursor based paging. As a bonus, (compared to using firestore-admin directly) using Flame will greatly reduce the amount code in API endpoints and Lambda functions that interact with Firestore.
If you have any ± feedback, feature requests, or bug reports, please open an issue on Github.
Install flame-odm using yarn or npm.
At this time, Flame targets node.js and will not work in the browser.
Note: Flame works alongside existing installations of firebase-admin in your project.
The connection to Firestore is defined as part of an Adapter. If you are using Firebase Functions, Flame's default Adapter will connect automatically. The following example shows how to define the connection manually using a service account.
Note: Flame doesn't immediately create a database connection. When queries are run, the Adapter lazily connects to Firestore as needed.
Let's create our first Model using the Adapter we just defined.
Now, we can use our User Model to create a Record.
Then, we can save the Record we just created as a document to Firestore.
Finally, we can execute a Query to retrieve the document saved in Firestore.
Create an Access that can be used to screen Objects using a role-basd mask.
Object that mirrors defaults on the target Model, where the value of each field is an Array of roles allowed to access the given field.Access.
List the fields allowed by an Access, given one or more roles.
Creates a copy of obj including only role-allowed fields.
Create an Adapter which can be used as a mixin when creating a Model or Record.
When service_account is 'firebase-function' or 'google-cloud' the service account will be retrieved automatically from the respective platform.
When service_account is 'process-env' Flame will look for the service account as a JSON string stored at process.env.FB_SERVICE_ACCOUNT.
When service_account is an Object, Flame assumes the Object is the service account.
When service_account is a Function, Flame will invoke service_account(), which should return a Promise that resolves to a service account Object.
When unspecified, Flame will default to using 'firebase-function'.
Note: If you are using Flame in a Firebase Function, you do not need to define or use an Adapter. Flame will automatically use the default Adapter and connect as needed.
Create multiple Adapters with different app_names to connect to multiple Firestore databases.
If service_account is: 'google-cloud', 'firebase-function', or null then app_name is ignored.
Adapter.
Avoid calling Adapter.connect() directly, it is invoked automatically by Adapter, Model, and Record methods as needed.
Connect to Firestore.
Executes a set of database operations as a transaction.
The argument fn is a Function invoked with one argument: T (Transaction) which may be passed to any read or write methods carried out within the context of Adatper.transact.
fn.
Create a Config which is used to store and pass configuration options to other constructors.
Object of { field: value, ...} entries allowed by the constructor or method that will recieve Config.Config.
Create a Model. A Model defines the structure of the documents to be stored in Firestore.
This Model's type.
By default, type will be the collection in Firestore for documents saved by Records created from this Model. However, the collection can be overriden with a custom Config.
The structure of your Model defined by an Object of {field: value, ...} entries, where value can be any of: Array, Boolean, Number, Null, Object, String, or Function.
When value is a Function, it will be invoked with two arguments: type and values where type is the Model's type and values is a clone of defaults.
Model's constructor of (Type), the Model's corresponding default (Type) will be overridden.Model.
Count the number of documents in a collection that satisfy query.
Query that determines what to count. If query is not specified, all documents in the collection are counted.Promise that resolves to the Integer number of documents in the collection that satisfy query, or Null if Model.count() fails.
Create a new Record.
Object of the values for Record. values will be merged with the Model's defaults.Model.create() of (Type), the created Record's corresponding default (Type) will be overridden.Record.
Extend a Model.
This Model's type.
By default type will be the collection used in Firestore when saving a Record. However, the collection can be overriden with a custom Config.
The structure of your Model defined by an Object of {field: value, ...} entries, where value can be any of: Array, Boolean, Number, Null, Object, String, or Function. defaults will be merged with the extended Model's defaults.
When value is a Function, it will be invoked with two arguments: type and values where type is the Model's type and values is a clone of defaults.
Model's constructor of (Type), the Model's corresponding default (Type) will be overridden.Model.
Retrieve the first document in a collection that satisfies query.
Query that determines what documents are elliglbe. If query is not specified, the first document in the collection is returnedObject. Use when invoking Model.find() within the context of Adapter.transact().Object, or Null if there is no match.
Retrieve all documents in a collection that satisfy query.
Query that determines what documents will be included. If query is not specified, all documents in the collection will be included.Object. Use when invoking Model.findAll() within the context of Adapter.transact().Null if there are no matches.
Create a partial Record using an existing document ID.
Object of the values for Record. values will be merged with the Model's defaults.Model.fragment() of (Type), the created Record's corresponding default (Type) will be overridden.Record.
Retrieve a single document from a collection.
Object. Use when invoking Model.get() within the context of Adapter.transact().Record Object, or Null if there is no document with the given id.
Retreive multiple documents from a collection.
Object. Use when invoking Model.getAll() within the context of Adapter.transact().Array of the document Objects, or Null if any of the provided ids do not correspond to a document in Firestore.
Retrieve a page of documents from a collection.
Pager to use.An Object that defines the current cursor and it's position.
When unspecified or Null, cursor defaults to the first document in the collection that satisfies pager.
Object. Use when invoking Model.getAll() within the context of Adapter.transact().Object, or Null if there are no documents that satisfy the supplied pager and cursor.
Traverse all documents in a collection that satisify the constraints of pager. fn is invoked once with each record as its first argument.
The Pager to use. When Pager is initalized with { size: 1 }, each invocation of fn will be in serial. Otherwise, fn will be invoked on all records in a given page in parallel.
Use size as a rate-limiter to ensure Model.traverse() doesn't exceed read or write limits.
An Object that defines the current cursor and it's position.
When unspecified or Null, the cursor defaults to the first document in the collection that satisfies pager.
Object, or Null if there are no documents that satisfy the supplied pager.
Creates a Pager that can be used to in combination with Model.page() to retrieve cursor-based pages from a collection in Firestore.
An Array of constraint tuples that defines what documents are included when retrieving a page using this Pager in combination with Model.page(). Each constraint tuple is represented using an Array in the form [constraint, field, value(s)].
The allowed constraint tuples are:
| Constraint Tuples | ||
|---|---|---|
'and' | One or more 'and', 'or, 'eq', 'eq-any', 'gt', 'gte', 'includes', 'includes-any', 'lt', 'lte', 'not-eq', 'not-eq-any' constraint tuples. | |
'or' | One or more 'and', 'or, 'eq', 'eq-any', 'gt', 'gte', 'includes', 'includes-any', 'lt', 'lte', 'not-eq', 'not-eq-any' constraint tuples. | |
'eq' | field (String) | value (Array|Boolean|Number|Null|Object|String) |
'eq-any' | field (String) | values (Array<Array|Boolean|Number|Null|Object|String>) |
'gt' | field (String) | value (Array|Boolean|Number|Null|Object|String) |
'gte' | field (String) | value (Array|Boolean|Number|Null|Object|String) |
'includes' | field (String) | value (Array|Boolean|Number|Null|Object|String) |
'includes-any' | field (String) | values (Array<Array|Boolean|Number|Null|Object|String>) |
'lt' | field (String) | value (Array|Boolean|Number|Null|Object|String) |
'lte' | field (String) | value (Array|Boolean|Number|Null|Object|String) |
'not-eq' | field (String) | value (Array|Boolean|Number|Null|Object|String) |
'not-eq-any' | field (String) | values (Array<Array|Boolean|Number|Null|Object|String>) |
'order-by' | field (String) | value (String) |
Object of the form { size: value (Integer) } where value is the number of documents per page.Pager.
Create a Query that can be used with Model.count(), Model.find(), and Model.findAll() to count and retrieve documents from Firestore.
An Array of constraint tuples that defines what documents are included when using this Query in combination with Model.count(), Model.find(), or Model.findAll(). Each constraint tuple is represented using an Array in the form [constraint, field, value(s)] or [constraint, value(s)].
The allowed constraint tuples are:
| Constraint Tuples | ||
|---|---|---|
'and' | One or more 'and', 'or, 'eq', 'eq-any', 'gt', 'gte', 'includes', 'includes-any', 'lt', 'lte', 'not-eq', 'not-eq-any' constraint tuples. | |
'or' | One or more 'and', 'or, 'eq', 'eq-any', 'gt', 'gte', 'includes', 'includes-any', 'lt', 'lte', 'not-eq', 'not-eq-any' constraint tuples. | |
'eq' | field (String) | value (Array|Boolean|Number|Null|Object|String) |
'eq-any' | field (String) | values (Array<Array|Boolean|Number|Null|Object|String>) |
'gt' | field (String) | value (Array|Boolean|Number|Null|Object|String) |
'gte' | field (String) | value (Array|Boolean|Number|Null|Object|String) |
'includes' | field (String) | value (Array|Boolean|Number|Null|Object|String) |
'includes-any' | field (String) | values (Array<Array|Boolean|Number|Null|Object|String>) |
'limit' | value (Integer) | |
'lt' | field (String) | value (Array|Boolean|Number|Null|Object|String) |
'lte' | field (String) | value (Array|Boolean|Number|Null|Object|String) |
'not-eq' | field (String) | value (Array|Boolean|Number|Null|Object|String) |
'not-eq-any' | field (String) | values (Array<Array|Boolean|Number|Null|Object|String>) |
'order-by' | field (String) | value (String) |
'start-at' | value (Array<Strings>) | |
Query.
Permanently removes the document represented by this Record from Firestore.
Object. Use when invoking Record.destroy() within the context of Adapter.transact().true if successful, otherwise false.
Produces an Object of the Record's fields that are not valid.
Array of fields to validate. When unspecified or Null, all fields are validated.Object in the form of { field: value (Boolean), ... } where each field is a field in the Record, and each value is true if the field fails this Record's corresponding Validator function.
Produces the Object representation of this Record's fields and values.
Record's as an Object.
Check if all fields of the Record are valid.
Null all fields are checked.true if all fields are valid, otherwise false.
Save this Record to Firestore as a document.
Object. Use when invoking Record.save() within the context of Adapter.transact().true when successful, otherwise false.
Update this Record's corresponding document in Firestore.
Record's document in Firestore.Object. Use when invoking Record.update() within the context of Adapter.transact().true when successful, otherwise false.
Create a Serializer that can be used to transform Record Object format into a Firestore document Object format, and vice-a-versa.
opts is an Object with three allowed fields: prefixes, separator, and fmt.
prefixes is an Array of prefixes that can be used to create 2-level Records that will be automatically flattened by Flame as they are written to Firestore, and documents retrieved from Firestore will automatically be expanded back into 2-level Objects.
separator is used as field concatenator between the prefixes and the 2nd-level field names for 2-level Records stored in Firestore.
fmt normalizes the casing for field names when in Firestore, and as Objects. Snake, kebabk, pascal, and camel cases are supported.
Serializer.
Create a Validator that can be used to check if a Record's fields are valid.
An Object of the form { field: validator } that mirrors the structure of the target Model, where the validator of each field is a Function.
Each validator is invoked with two arguments, value and object. value is the Record's corresponding field value, and object is the full Object representation of the Record.
Each validator should evaluate true if valid, false otherwise.
Validator.