npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@simpleclub/firestore-decorators

v0.0.10

Published

Decorators to help converting Firestore documents to classes.

Downloads

2

Readme

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.