# @typeheim/orm-on-fire

> Firestore ORM

Latest version **0.1.0** (published 2022-06-23) · MIT license · 0 weekly downloads

## Install

```sh
npm install @typeheim/orm-on-fire
pnpm add @typeheim/orm-on-fire
yarn add @typeheim/orm-on-fire
bun add @typeheim/orm-on-fire
```

## Health

**Score 20/100 (F)** — status: abandoned.

Positive: has types; no vulnerabilities.

Warnings: low downloads; no esm support; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.1.0 |
| Published | 2022-06-23 |
| First published | 2020-05-21 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 2 |
| Unpacked size | 157.6 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | Dima Kolodko |
| Maintainers | prowwid |
| Keywords | fire-legion, orm-on-fire, firestore, firebase, orm, odm, ddd, repository, entity, model, collections, typescript, ts, web, front-end, framework, angular, nest, back-end |

## Links

- npm: https://www.npmjs.com/package/@typeheim/orm-on-fire
- Homepage: https://github.com/typeheim/fire-legion/packages/orm-on-fire#readme
- Issues: https://github.com/typeheim/fire-legion/issues
- npm.io page: https://npm.io/package/@typeheim/orm-on-fire

## Dependencies (2)

- [reflect-metadata](https://npm.io/package/reflect-metadata.md) ^0.1.13
- [@typeheim/fire-rx](https://npm.io/package/@typeheim/fire-rx.md) ^0.2.0

## Alternatives

- [mobx-react](https://npm.io/package/mobx-react.md) — 2.8M weekly downloads
- [rc-tree](https://npm.io/package/rc-tree.md) — 2.6M weekly downloads
- [@react-oauth/google](https://npm.io/package/@react-oauth/google.md) — 1.3M weekly downloads
- [@wagmi/connectors](https://npm.io/package/@wagmi/connectors.md) — 877.0K weekly downloads
- [vee-validate](https://npm.io/package/vee-validate.md) — 836.4K weekly downloads

## Recent versions

- 0.1.0 (latest) — 2022-06-23
- 0.0.1 — 2021-08-06
- 0.0.0-beta.54 — 2021-06-09
- 0.0.0-beta.53 — 2021-06-01
- 0.0.0-beta.51 — 2021-04-20
- 0.0.0-beta.50 — 2021-03-31
- 0.0.0-beta.49 — 2021-03-14
- 0.0.0-beta.48 — 2021-03-08
- 0.0.0-beta.47 — 2021-02-17
- 0.0.0-beta.46 — 2021-02-16
- 0.0.0-beta.45 — 2021-02-16
- 0.0.0-beta.44 — 2021-02-15
- 0.0.0-beta.43 — 2021-01-28
- 0.0.0-beta.42 — 2021-01-11
- 0.0.0-beta.39 — 2021-01-11
- … 30 more at https://npm.io/package/@typeheim/orm-on-fire/versions

## README

<p align="center">
    <img style="max-width: 100%" width="1200" src="https://raw.githubusercontent.com/typeheim/fire-legion/46726290060f4631bb0fb10017bdf7954f7e21d9/packages/orm-on-fire/docs/orm-on-fire-logo.svg">
</p>
<p>
    <a href="https://www.npmjs.com/package/@typeheim/orm-on-fire" target="_blank"><img src="https://img.shields.io/npm/v/@typeheim/orm-on-fire.svg" alt="NPM Version" /></a>
    <a href="https://app.buddy.works/typeheim/fire-legion/pipelines/pipeline/300564" target="_blank"><img src="https://app.buddy.works/typeheim/fire-legion/pipelines/pipeline/300564/badge.svg?token=aad32357cefae9d70b31d8b440fdf3f3d5d2a244a0412ff42ac294abbfc508f5" alt="Build Status" /></a>
    <a href="https://www.npmjs.com/package/@typeheim/orm-on-fire" target="_blank"><img src="https://img.shields.io/npm/l/@typeheim/orm-on-fire.svg" alt="Package License" /></a>
    <a href="https://discord.gg/dmMznp9" target="_blank"><img src="https://img.shields.io/badge/discord-online-brightgreen.svg" alt="Discord"/></a>
</p>

ORMOnFire is a powerful Firestore ORM.

## Installation
Install package

```shell
# in backend
yarn add firebase firebase-admin firebase-tools

# in frontend
yarn add firebase 

yarn add @typeheim/orm-on-fire
# or
npm -i @typeheim/orm-on-fire
```

Setup ORMOnFire driver:

```typescript
// sample for Node.JS
FirebaseAdmin.initializeApp({
    credential: FirebaseAdmin.credential.cert('my.key.json'),
    databaseURL: "https://my-db.firebaseio.com",
})
OrmOnFire.driver = FirebaseAdmin.firestore()
```

## Easy entity declaration

To define entity you need to use `@Entity` or `@Agregate` decorators for simple and nested collections. Note both
decorators will transform class name to kebab case - lowercase and split words with hyphens, like `UserFiles` <
=> `user-files`.

Then, each document field must be decorated with `@Field`, `@MapField`, `@CreatedDateField`, `@UpdatedDateField`
or `@DocRef`(for document references) decorators. Sub-collections can be referenced by `@CollectionRef` decorator.

```typescript
import {
    Agregate,
    Entity,
    Collection,
    CollectionRef,
    ID,
    Field,
    CreatedDateField,
    UpdatedDateField,
    MapField
} from '@typeheim/orm-on-fire'
import { CreatedDateField } from './Entity'

@Agregate()
export class User {
    @ID() id: string

    @Field() firstName: string

    @Field() lastName: string

    @Field() status: string

    @CollectionRef(UserFile) files: Collection<UserFile>
}

@Entity({ collection: 'user-files' })
export class UserFile {
    @ID() id: string

    @Field() name: string

    @MapField() properties: FileProperties

    @CreatedDateField() createdAt: Date

    @UpdatedDateField() createdAt: Date
}

class FileProperties {
    type: "image" | "doc"
}
```

## Simple data fetching

```typescript
import { Collection } from '@typeheim/orm-on-fire'

// with promise-like interface
let markus = await Collection.of(User).one('markus').get()

// with Rx interface
Collection.of(User).one('tom').get().subscribe((tom: User) => {
    tom.files.forEach((file: UserFile) => {
        // some cool stuff
    })
}) 
```

## Powerful filtering

### Using firestore operators

```typescript
import { Collection } from '@typeheim/orm-on-fire'
const UsersCollection = Collection.of(User)

// Search using regular Firesotre operators
let activeUsers = await UsersCollection.all().filter(user => user.status.equal('active')).get()
let notActiveUsers = await UsersCollection.all().filter(user => user.status.notEqual('active')).get()
let adultUsers = await UsersCollection.all().filter(user => user.age.greaterThan(18)).get()
```

### Test index search

To use text index search you first need to add text index hook Firebase function to your Firebase functions list for
each colelction you want to be idndexed

```typescript
import { TextIndex } from '@typeheim/orm-on-fire'
import * as functions from 'firebase-functions'
import * as FirebaseAdmin from 'firebase-admin'

FirebaseAdmin.initializeApp()

export const generateUserIndex = TextIndex(functions, FirebaseAdmin).forCollection('users')
                                                     .fields(['name', 'text'])
                                                     .buildTrigger()
```

Official functions deployment
guide: [Get started: write, test, and deploy your first functions](https://firebase.google.com/docs/functions/get-started)

Once you deploy hooks, you can use index search as below:

```typescript
// Note: text index search is case-insensitive 
let usersStartsWithAlex = await UsersCollection.all().useIndex(user => user.firstName.startsWith('Alex')).get()
let usersEndsWithLex = await UsersCollection.all().useIndex(user => user.firstName.endsWith('lex')).get()
```
NOTE: for now text index won't work with collection group queries. Support coming in next releases.

## Filter scopes:

Commonly used filer conditions can be organized in named filter scopes for easy code reuse:

```typescript
class UserScope {
    static active() {
        return (user: EntityFilter<User>) => {
            user.status.equal(1)
        }
    }
}

// fetch all active users
let activeUsers = await UsersCollection.all().filter(UserScope.active()).get()
```

## Sub-collection queries:

For nested collections you don't need to fetch each document separately and can access required collection under
specific document ID:

```typescript
// fetch all PDF files from user suwth id "userId"
let userFiles = await UsersCollection.one('userId').collecction(UserFile).filter(UserFile.pdf()).get()
```

## Group collection queries:

ORMOnFire support easy declaration
of [collection groups](https://firebase.googleblog.com/2019/06/understanding-collection-group-queries.html) the same way
as for regular collections.

```typescript
// fetch all file attachments that exist in any collection and sub-collection
let attechments = await Collection.groupOf(Attachment).all().filter(Attachment.file()).get()
```

---
_Source: https://npm.io/package/@typeheim/orm-on-fire · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
