Skip to content Skip to sidebar Skip to footer

What Will Happen If I Set The Request's Mode To 'no-cors' In My Firebase Cloud Function?

This is a follow up to this question. I have a firebase function which is supposed to take an OTP, validate it and then change a user's password based on whether it is correct or n

Solution 1:

Have a look at the documentation for Callable Cloud Functions:

  1. You don't need to encapsulate it in return new Promise((resolve, reject) => {});
  2. You need to return data that can be JSON encoded;
  3. You need to manage the errors correctly, by by throwing (or returning a Promise rejected with) an instance of functions.https.HttpsError;
  4. You need to correctly chain all the promises returned by the asynchronous methods.

I've tried below to re-organized your code in the lights of the points above, but since your business logic is complex I cannot test it and there might be other approaches to manage all the cases... Up to you to "polish" this first attempt! Hoping it will help.

exports.resetPassword = functions.https.onCall((data, context) => {

        if(data.sesId && data.otp){

            let dataOptCorresponds = true;

            return admin.firestore().collection('verification').doc(data.sesId).get()
            .then(verSnp => {
                if(verSnp.data().attempt != 'verified'){

                    var now = newDate().getTime()

                    if(verSnp.data().expiring > now){
                        if(data.email == verSnp.data().email){
                            if(verSnp.data().attempt > 0){
                                if(data.otp == verSnp.data().otp){
                                    return admin.auth().getUserByEmail(data.email);
                                } else {
                                    dataOptCorresponds = false;
                                    var redAttempt = verSnp.data().attempt - 1return admin.firestore().collection('verification').doc(data.sesId).update({
                                        attempt: redAttempt
                                    })
                                }
                            } else {
                                thrownewError('Incorrect OTP. You have exhausted your attempts. Please request a new OTP.')
                            }
                        } else {
                            thrownewError('Incorrect email. How did you get here?')
                        }
                    } else {
                        thrownewError('OTP is expired. Please request a new OTP.')
                    }
                } else {
                    thrownewError('OTP is invalid. Please request a new OTP.')
                }
            })
            .then(user => {
                if(dataOptCorresponds) {
                    return admin.auth().updateUser(user.uid,{
                        password: data.password
                    })
                } else {
                    thrownewError(`Incorrect OTP. You have xxxx attempts remaining.`)
                }
            })
            .then(() => {
                return admin.firestore().collection('verification').doc(data.sesId).update({
                    attempt: 'verified'
                })
            .then(() => {
                return {result: "success"}                      
            })          
            .catch(error => {
                thrownew functions.https.HttpsError('internal', error.message);

            })

        } else {

            thrownew functions.https.HttpsError('invalid-argument', 'Enter OTP');
        }

})

UPDATE following Bergi's comment below:

If you want to be able to differentiate the kind of errors returned to the front-end (in particular sending back an invalid-argumentHttpsError if the OTP is incorrect, invalid or expired or if the email is incorrect) you may use a second argument in the then() method.

exports.resetPassword = functions.https.onCall((data, context) => {

        if(data.sesId && data.otp){

            let dataOptCorresponds = true;

            return admin.firestore().collection('verification').doc(data.sesId).get()
            .then(

                verSnp => {
                    if(verSnp.data().attempt != 'verified'){

                        var now = newDate().getTime()

                        if(verSnp.data().expiring > now){
                            if(data.email == verSnp.data().email){
                                if(verSnp.data().attempt > 0){
                                    if(data.otp == verSnp.data().otp){
                                        return admin.auth().getUserByEmail(data.email);
                                    } else {
                                        dataOptCorresponds = false;
                                        var redAttempt = verSnp.data().attempt - 1return admin.firestore().collection('verification').doc(data.sesId).update({
                                            attempt: redAttempt
                                        })
                                    }
                                } else {
                                    thrownewError('Incorrect OTP. You have exhausted your attempts. Please request a new OTP.')
                                }
                            } else {
                                thrownewError('Incorrect email. How did you get here?')
                            }
                        } else {
                            thrownewError('OTP is expired. Please request a new OTP.')
                        }
                    } else {
                        thrownewError('OTP is invalid. Please request a new OTP.')
                    }
                },

                error => {

                    thrownew functions.https.HttpsError('invalid-argument', error.message);

                }

            )
            .then(user => {
                if(dataOptCorresponds) {
                    return admin.auth().updateUser(user.uid,{
                        password: data.password
                    })
                } else {
                    thrownewError(`Incorrect OTP. You have xxxx attempts remaining.`)
                }
            })
            .then(() => {
                return admin.firestore().collection('verification').doc(data.sesId).update({
                    attempt: 'verified'
                })
            .then(() => {
                return {result: "success"}                      
            })          
            .catch(error => {
                thrownew functions.https.HttpsError('internal', error.message);

            })

        } else {

            thrownew functions.https.HttpsError('invalid-argument', 'Enter OTP');
        }

})

Post a Comment for "What Will Happen If I Set The Request's Mode To 'no-cors' In My Firebase Cloud Function?"