2023-01-15

How to send params of current request to the constructor of the service?

Update: I have fixed it by only supplying the pattern of the path of the collection, and creating a function that can parse the provided IDs and now the functions themselves create the collections when they are called upon and it also works with Typescript:)

Updated in the repository: https://github.com/Darkbound/nestjs-firebase/tree/main/src/firebase

In the user service: https://github.com/Darkbound/nestjs-firebase/blob/main/src/user/user.service.ts

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

In the purchase transactions controller: https://github.com/Darkbound/nestjs-firebase/blob/main/src/user/modules/purchase-transaction/purchase-transaction.controller.ts#L14


https://github.com/Darkbound/nestjs-firebase I have uploaded it into a repository, you only need to add .env with the keys for firebase admin.

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

I have created a class that gives me the functionality to perform CRUD operations on firebase, so that I can just directly inherit from it for any of my CRUD resources, as the logic is again usually mostly the same. Just like Nestjs generator gives me all of the routes for it.

@Injectable()
export class UserService extends NestjsFirebase<User> {
  constructor(@InjectFirebaseAdmin() firebase: FirebaseAdmin) {
    super(firebase, "users");
    // console.log(userId);
  }
}

This works great, I can reuse that for any level 1 collection I have in firebase, however if I want to get into a nested collection on firebase, well thats a problem, because the path there needs to be dynamic and super(firebase, "this is no longer just users").

Say if I want to access the transactions of a user, so users/SomeUserIdXYZ/transactions, then the path is entirely dependent on the userId and is changing, therefor, I need to recreate the instance of the service (I simply need a new instance of the class), with a new path:

super(firebase, ["users", userId, "transactions"]

However with my still limited knowledge about Nestjs I know that everything in it basically is a Singleton and there is probably no way to do this? To get a new instance of the service, for every request that I have?

The solution that I can think of is, to handle that within my route functions, so if its a findTransactions:

  @Get("users/:userId/transactions")
  async findTransactions(@Param("userId") userId: string) {
    return this.userService.findAll(`users/${userId}/transactions`);
  }

And I am pretty sure that this will work, if I add a path argument to each of the functions, but this seems like coupling the Controller with what my Path in firebase should look like, instead I need to be able to give it just the params so that it can create its own path.

This is NestjsFirebase:

@Injectable()
class NestjsFirebase<T> {
  constructor(@InjectFirebaseAdmin() private readonly firebase: FirebaseAdmin, private readonly collectionPath: string) {}

    async findAll(userId: string): Promise<T> {
      const db = new FirebaseCollectionService<T>(this.firebase, this.collectionPath);

      return await db.findAll(userId);
    }
}

export class FirebaseCollectionService<T> {
  protected db: CollectionReference<T>;

  constructor(firebase: FirebaseAdmin, collectionPath: string) {
    super(firebase.db);

    this.db = this.createCollectionPath(collectionPath);
  }

  public async findAll(id: string) {
     ... some logic to find all transactions ...

  }
}


No comments:

Post a Comment