2

I am trying to implement firebase functions using typescript. So far I was able to create some functions without problem until I had to deal with authentication. This is my first time using typescript, so I may be asking something that is obvious for most of the developers.

Context:

I was able to implement authentication check using this example. As we can see in that example (javascript) the code is decoding the token and passing the user information to the request, which will be processed by the next function.

Problem:

My problem is that I do not know how to do that in typescript. First of all, I had to add some types to the parameters in my token validator functions as the compiler was complaining about not having a type (like in the javascript example), so I went for something like this:

const validateFirebaseIdToken = async (req: any, res: any, next: any) 

The problem is that in my next function I am not able to get the user:

example.get('/', async (req, res) => {
  req.user
}

I receive the error: Property 'user' does not exist on type 'Request < Dictionary< string>>'.

so, how would you do it in this case? I do not want to decode the token again in the second function because it wouldn't make sense (I already did that in the previous step (token validation)).

Ideally:

  • I would like to use the same approach as it is in the javascript example.

  • I would like to add the right type to the parameters in the toke validation function. I tried using Request < Dictionary< String>> butthe compiler complains saying that that type is not generic (I deduced the type from the second function)

This is my code:

const validateFirebaseIdToken = async (req: any, res: any, next: any) => {}

const example = express();
example.use(validateFirebaseIdToken);
example.get('/', async (req, res) => {}
7
  • How does the request look like, that you send to your function? Commented Sep 2, 2019 at 8:05
  • @ConstantinBeer do you mean the request from the client? if that is so, then it is like a normal http request with the token to authenticate. So far the authentication is working without problem. I just need to do some operations related to the user that is making those requests. That is why I need to get the user information in my second function. Commented Sep 2, 2019 at 8:10
  • 1
    Try to use req.body.user Commented Sep 2, 2019 at 8:16
  • 1
    Hi @chrismclarke. Thanks for the tip. I just want to try to keep using typescript's features like static typing which is the reason why I decided to move from javascript to this language. Commented Sep 2, 2019 at 9:20
  • 1
    @ConstantinBeer your suggestion worked for me. Do you want to add a proper answer so that I can accept it? Commented Sep 3, 2019 at 11:45

3 Answers 3

2

Something to add to the accepted answer given by @Constantin:

Ideally:

  • I would like to use the same approach as it is in the javascript example.

Besides the answer given by Constantin, I needed to add a type to the request.

req: express.Request

  • I would like to add the right type to the parameters in the toke validation function. I tried using Request< Dictionary < String>> but the compiler complains saying that that type is not generic (I deduced the type from the second function)

I ended up having this method:

const validateFirebaseIdToken = async (req: express.Request, res: express.Response, next: any) => {}
Sign up to request clarification or add additional context in comments.

Comments

1

Your request includes a body that holds your user. So you have to do it like this:

example.get('/', async (req, res) => {
     req.body.user
}

Comments

1

I think the recommended way to achieve this is using Declaration merging as stated here.

  1. Create a type.d.ts file in the src folder with the following code:
import { auth } from "firebase-admin";

declare global {
  namespace Express {
    export interface Request {
      user: auth.DecodedIdToken;
    }
  }
}

By using Declaration merging and specifying the type for the user prop you will get autocomplete support.

  1. Optionally, if you want to be very strict with the types, instead of using express.Request do the following:
import * as expressTypes from "express-serve-static-core";

const validateFirebaseIdToken = async (
  req: expressTypes.Request<expressTypes.Dictionary<string>>,
  res: expressTypes.Response,
  next: expressTypes.NextFunction
) => {};

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.