@simpleclub/firestore-decorators
TypeScript icon, indicating that this package has built-in type declarations

0.0.10 • Public • Published

Firestore decorators for Typescript

Firestore decorators is an provides a convenient method to generating Firestore converters automagically. It can be used with Typescript.

This library currently only supports the admin Firebase SDK.

It is inspired by the Firebase Firestorm library, but less opinionated how you should use the model. It only parses models from Firestore documents to models and nothing more.

Contents

Requirements

Firestore decorators relies on using Typescript's experimental decorators for defining your models. Please ensure you have the following in your tsconfig.json (ES5 is minimum target):

{
  "compilerOptions": {
    "target": "ES5",
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}

Installation

For npm:

$ npm install firebase-decorators

For yarn:

$ yarn add firebase-decorators

Usage

Getting Started

Learn how to set up and us Firestore decorators to auto-generate Firestore converters.

1. Initialize decorators

Call decorators.initialize(firestore, options?) as soon as you initialize your firestore app. See initialization options for more information about initializing Firestore decorators.

import * as decorators from 'firestore-decorators';
...
const firestore = firebase.initializeApp(...).firestore();
decorators.initialize(firestore, /* options */);
...

2. Defining collection models

Here we have a class representing a posts collection. Entity classes are typically non-pluralized as they represent a single document from that collection. To define a collection you must:

  • Extend from the Entity class.
  • Annotate your class with @collection(opts: ICollectionConfig).
  • Declare a series of fields, annotated with @field(opts: IFieldConfig).
import { Entity, collection, field } from 'firestore-decorators';

@collection({
  path: 'posts',
})
export default class Post extends Entity {
  @field({ name: 'title' })
  title!: string;

  @field({ name: 'content' })
  content!: string;
}

3. Defining subcollections

Each of your models, whether they represent a root collection or subcollection must extend from the Entity class provided.

Now we want documents in the posts collection to have a subcollection of comments. First, we need to create a class for the comments. We also annotate the class with @collection, ] but we use placeholders for the post ID.

import { Entity, collection, field } from 'firestore-decorators';

@collection({
  path: 'posts/{post}/comments',
})
export default class Comment extends Entity {
  @field({ name: 'content' })
  content!: string;

  @field({ name: 'by' })
  by!: string;
}

4. Defining document references

Finally, we want documents in the posts collection to reference an author in an authors collection (another root collection). First, we define the Author entity:

import { Entity, collection, field } from 'firestore-decorators';

@collection({
  path: 'authors',
})
export default class Author extends Entity {
  @field({ name: 'name' })
  name!: string;
}

Then we can add an Author reference to the Post entity using the @documentRef(opts: IDocumentRefConfig) decorator:

import {firestore} from 'firebase-admin';
import { Entity, collection, documentRef } from 'firestore-decorators';
import Author from './Author';

@collection({
  path: 'posts',
})
export default class Post extends Entity {
  @documentRef({
    name: 'author',
    entity: Author
  })
  author!: firestore.DocumentReference<Author>;
  ...
}

Custom Data Types

Arrays

Firestore documents can contain arrays of strings, numbers, objects, etc. Defining arrays in Firestore decorators is as simple as assigning properties as array types in your Entity files. For example:

class Example extends Entity {
  @field({ name: 'example_property_1' })
  property1!: string[];

  @field({ name: 'example_property_2' })
  property2!: firestore.DocumentReference<AnotherEntity>[];
}

Nested Data

Firestore documents can contains nested objects (or maps). For a nested object, you need to create a new class to represent that object, and add a property with that class in your Entity, wrapped with the @map decorator.

class Example extends Entity {
  @map({ name: 'nested_object' })
  nestedObject!: Nested;
}

class Nested {
  @field({ name: 'nested_property' })
  nestedProperty!: string;
}

And then to use this entity:

const nested = new Nested();
nested.nestedProperty = 'test';
const example = new Example();
example.nestedObject = nested;

Important: If your is nested data is an array you must provide the 'entity' option in the configuration.

class Nested {
  @map({ name: 'nested_array', entity: Nested })
  nestedObject: Nested[];
}

Geopoints

Geopoints store locational data and can be used as fields.

class Example extends Entity {
  @geoPoint({
    name: 'geopoint_property',
  })
  geopoint!: firestore.GeoPoint;
} 

And then to assign a GeoPoint:

const example = new Example();
example.geopoint = new firestore.Geopoint(latitude, longitude);

Timestamps

You can represent date & time data in your Entity files.

class Example extends Entity {
  @timestamp({
    name: 'timestamp_property',
  })
  timestamp!: firestore.Timestamp;
}

Initialization Options

Firestore decorators.intialize({ ...opts : IFireormConfig }) can be called with the following options:

Option Description Type
fieldConversion Providing this option will convert Entity propertity names into firestore collection names so you don't need to provide the name option in @field() decorators. To view available values please check out the docs. enum FieldConversionType

Development

Setup

  1. Clone the repo.
  2. Install dependencies.
cd firestore-decorators 
yarn install

Testing

The testing script looks for *.spec.ts files in the src and test directory.

yarn test

Contributing

Found a bug?

Please report any bugs you have found submitting an issue to our Github repository, after ensuring the issue doesn't already exist. Alternatively, you can make a pull request with a fix.

Pull Requests

If you would like to help add or a feature or fix a bug, you can do so by making a pull request. The project uses Conventional Commits, so please make sure you follow the spec when making PRs. You must also include relevant tests.

License

INSERT LICENSE

Contributing

If you wish to contribute a change in this repo, please review our contribution guide, and send a pull request.

Package Sidebar

Install

npm i @simpleclub/firestore-decorators

Weekly Downloads

1

Version

0.0.10

License

BSD-3-Clause

Unpacked Size

87.4 kB

Total Files

76

Last publish

Collaborators

  • simpleclub-owner