This project helps you to use your Firestore collections in a well known way, similar* to how TypeORM lets you to handle your tables.
The principal benefits are:
- Model your collections using classes (similar on how ORMs works).
- Simplify the testing of the Firestore SDK.
*This is NOT an ORM.
In order to install this package simply run the following command.
npm install @cristobalgvera/nestjs-firestore
The simplest way to use it is the following:
-
Import the
FirestoreModule#forRoot
into your main module.import { FirestoreModule } from '@cristobalgvera/nestjs-firestore'; import { Module } from '@nestjs/common'; @Module({ imports: [ FirestoreModule.forRootAsync({ useFactory: (environmentService: EnvironmentService) => ({ // You can define custom properties here, see https://github.com/googleapis/nodejs-firestore projectId: 'firebase-project-id', }), }), ], }) export class AppModule {}
-
Define your model (currently only classes are supported).
export class User { name: string; age: number; }
-
Import the
FirestoreModule#forFeature
into your feature module.import { FirestoreModule } from '@cristobalgvera/nestjs-firestore'; import { Module } from '@nestjs/common'; import { User } from './user.collection'; @Module({ imports: [ FirestoreModule.forFeature([ { collection: User, path: 'path-to-your-collection' }, ]), ], }) export class UserModule {}
-
Inject the collection into your services using the
InjectCollection
decorator and theFirestoreCollection
type. TheFirestoreCollection
needs a generic class (soon type or interface too) in order to type your collection.The
FirestoreCollection
is a wrapper on top of theCollectionReference
type provided by@google-cloud/firestore
, so you can use the entire API, but it will provide correct typing based in the collection class.import { FirestoreCollection, InjectCollection, } from '@cristobalgvera/nestjs-firestore'; import { Injectable } from '@nestjs/common'; import { User } from './user.collection'; @Injectable() export class UserService { constructor( @InjectCollection(User) private readonly userCollection: FirestoreCollection<User>, ) {} saveUser({ name, age }: SaveUserDto) { return this.userCollection.add({ name, age }); } }
-
Test it using the
getCollectionToken
to get the token used to inject the collection in the service.import { TestBed } from '@automock/jest'; import { FirestoreCollection, getCollectionToken, } from '@cristobalgvera/nestjs-firestore'; import { User } from './user.collection'; import { UserService } from './user.service'; describe('UserService', () => { let underTest: UserService; let userCollection: FirestoreCollection<User>; beforeEach(() => { // Don't focus on how to create the context of the test const { unit, unitRef } = TestBed.create(UserService).compile(); underTest = unit; userCollection = unitRef.get(getCollectionToken(User)); // <-- THIS IS THE IMPORTANT PART }); /* Your tests here... */ });