Skip to content

Adding support for CRUD operations with Firebase by extending Nestjs Controllers #1450

@Darkbound

Description

@Darkbound

Hello, I have never contributed before to a project and I dont really know exactly how to integrate my code into a PR for this one, so if you can guide me through it and you like what I did, I'd be happy to.

https://github.com/Darkbound/nestjs-firebase

https://github.com/Darkbound/nestjs-firebase/tree/main/src/firebase here I have a FirebaseCollectionService class that can be used to extend a NestjsController and give it CRUD methods for collections (nested too) out of the box:

import { Injectable } from "@nestjs/common";
import { FirebaseAdmin } from "nestjs-firebase/lib/firebase.interface";
import { InjectFirebaseAdmin } from "nestjs-firebase/lib/firebase.decorator";
import { User } from "./entities/user.entity";
import { FirebaseCollectionService } from "src/firebase/firebase-collection.service";
import { UpdateUserCreditsDto } from "./dto/update-user-credits.dto";

@Injectable()
export class UserService extends FirebaseCollectionService<User> {
  constructor(@InjectFirebaseAdmin() firebase: FirebaseAdmin) {
    super(firebase, "users");
  }
}

This is for a "level 1" collection, you instantiate it once for the service, give it firebase admin and the pattern of the collection path.

This will expose findOne, findAll, create, delete, update methods to the controller.

Basically if you run nest generate resource user and then delete the contents of the user.service.ts and just extend with my FirebaseCollectionService it will work directly with firebase

Now with purchase-transactions which is a nested collection of users, so users/{userId}/purchase-transactions/{transactionId}, you instantiate it the same way, but the second argument is the path, with the keys that are going to change for each document:

https://github.com/Darkbound/nestjs-firebase/blob/main/src/user/modules/purchase-transaction/purchase-transaction.service.ts

// This type is only for the keys within the path to the collection, as the last key is the "normal" `id` that comes from the controller itself and it can be named anything.
type FirebaseCollectionPathParams = {
  userId: string,
}

@Injectable()
export class PurchaseTransactionService extends FirebaseCollectionService<PurchaseTransaction, FirebaseCollectionPathParams> {
  constructor(@InjectFirebaseAdmin() firebase: FirebaseAdmin) {
    super(firebase, "users/{userId}/purchase-transactions");
  }
}

The path that is being supplied is the path of the collection.

Now in purchase-transactions.controller.ts, if I want to get a certain transaction:

@Get(":transactionId")
findOne(@Param("userId") userId: string, @Param("transactionId") transactionId: string) {
  return this.purchaseTransactionService.findOne(transactionId, { userId }); // Typescript for `userId` works
}

Let me know if you like it and would like it integrated, and if you can guide me through the process, I'd be more than happy to do it! :)

I guess it can probably be made into an Injectable module, just like your firebase admin, but I am still relatively new to Nestjs, so thats why I did not head that way :) Maybe that will be the next thing I will try to do...

Any recommendations are more than welcome!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions