1

I am trying to create an API for my Firebase project using functions. The difficult part is that I am using TypeScript and I keep running into typing problems.

This is my sign up route:

app.post('/signup', (req: Request, res: Response) =>{
  const newUser = {
    email: req.body.email,
    password: req.body.password,
    confirmPassword: req.body.confirmPassword,
    handle: req.body.handle
  }
  // TODO: validate data
  db.doc(`/users/${newUser.handle}`).get()
    .then( doc => {
      // Duplicated handle
      if(doc.exists){
        return res.status(400).json({ handle: 'this handle is already taken'});
      }
      // Valid handle
      else {
        return firebase.auth().createUserWithEmailAndPassword(newUser.email, newUser.password); 
      }
    })
    .then( data => {
      return data.user.getIdToken();
    })
    .then( token => {
      return res.status(201).json({ token });
    })
    .catch( err => {
      console.error(err);
      return res.status(500).json({ error: err.code })
    });
})

Errors:

  1. The doc in the first has the following error

Argument of type '(doc: DocumentSnapshot) => Response | Promise' is not assignable to parameter of type '(value: DocumentSnapshot) => UserCredential | PromiseLike'.

This is because I am returning a response status if the handle already exists, to avoid duplicates. From my understanding, this would go to the catch; and the valid handle would return a Promise that the next then would take. However, this is not working

  1. data.user.getIdToken() says that

Property 'user' does not exist on type 'DocumentSnapshot'. Tried delcaring a const for user before using it, but get the same message.

I have other functions for post and get from firestore working, but can't get the authentication ones to work.

Thanks for the help!

0

1 Answer 1

1

I've not tested your code but both your problems most probably come from the fact that you are calling firebase.auth().createUserWithEmailAndPassword() and getIdToken(), which are methods of the JavaScript SDK.

In a Cloud function, you need to use the Admin SDK, and therefore call the createuser() method.

  db.doc(`/users/${newUser.handle}`).get()
    .then( doc => {
      // Duplicated handle
      if(doc.exists){
        return res.status(400).json({ handle: 'this handle is already taken'});
      }
      // Valid handle
      else {
        return admin.auth().createUser(newUser.email, newUser.password); 
      }
    })
    .then(userRecord => {
      //... see below 
    })

Note that we replace firebase by admin, in order to use the Admin SDK. Don't forget to initialize it with const admin = require('firebase-admin'); admin.initializeApp();. See https://firebase.google.com/docs/functions/get-started?authuser=0#import-the-required-modules-and-initialize-an-app.

Then, you are using getIdToken() which is, again, a method from the JavaScript SDK.

You need to adapt your code depending on what was your exact goal by sending back a token to the front-end.

If you want to login the user in the front-end, just send back the info that the user was successfully created, and, in the front-end, call the signInWithEmailAndPassword() method.


Finally note two other important points:

  1. You should use a Transaction to check that the user doc is not existing
  2. The db variable shall be declared as admin.firestore().
Sign up to request clarification or add additional context in comments.

2 Comments

createUser(newUser.email, newUser.password) does not exist on type auth, so that didn't help. I'll try to look more into Admin SDK documentation. Thanks anyways!
Sorry it was a mistake from my side: I didn't replace all what needed to be replaced... you need to do admin.auth().createUser(newUser.email, newUser.password); instead of firebase.auth().createUserWithEmailAndPassword(newUser.email, newUser.password);. Note that we replace firebase by admin, to use the Admin SDK. Don't forget to initialize with const admin = require('firebase-admin'); admin.initializeApp();

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.