Reputation: 95
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:
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
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!
Upvotes: 1
Views: 474
Reputation: 83068
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:
db
variable shall be declared as admin.firestore()
.Upvotes: 1