Javascript 如果我设置请求';s模式转换为';无cors';在我的firebase云函数中?

Javascript 如果我设置请求';s模式转换为';无cors';在我的firebase云函数中?,javascript,firebase,cors,google-cloud-functions,es6-promise,Javascript,Firebase,Cors,Google Cloud Functions,Es6 Promise,这是问题的后续行动。我有一个firebase函数,它应该接受OTP,验证它,然后根据用户密码是否正确来更改用户密码(出于某种原因,我无法使用firebase的内置密码重置功能)。以下是我的职责: exports.resetPassword = functions.https.onCall((data, context) => { return new Promise((resolve, reject) => { if(data.sesId &&

这是问题的后续行动。我有一个firebase函数,它应该接受OTP,验证它,然后根据用户密码是否正确来更改用户密码(出于某种原因,我无法使用firebase的内置密码重置功能)。以下是我的职责:

exports.resetPassword = functions.https.onCall((data, context) => {
    return new Promise((resolve, reject) => {
        if(data.sesId && data.otp){
            admin.firestore().collection('verification').doc(data.sesId).get().then(verSnp => {
                if(verSnp.data().attempt != 'verified'){
                    var now = new Date().getTime()
                    if(verSnp.data().expiring > now){
                        if(data.email == verSnp.data().email){
                            if(verSnp.data().attempt > 0){
                                if(data.otp == verSnp.data().otp){
                                    admin.auth().getUserByEmail(data.email).then(user => {
                                        admin.auth().updateUser(user.uid,{
                                            password: data.password
                                        }).then(() => {
                                            admin.firestore().collection('verification').doc(data.sesId).update({
                                                attempt: 'verified'
                                            }).then(() => {
                                                Promise.resolve()
                                            }).catch(() => {
                                                throw new Error('Error updating the database.')
                                            })
                                        }).catch(() => {
                                            throw new Error('Error updating the password. Please try again.')
                                        })
                                    }).catch(() => {
                                        throw new Error('Incorrect email. How did you get here?')
                                    })
                                } else {
                                    var redAttempt = verSnp.data().attempt - 1
                                    admin.firestore().collection('verification').doc(data.sesId).update({
                                        attempt: redAttempt
                                    }).then(() => {
                                        throw new Error(`Incorrect OTP. You have ${redAttempt} attempts remaining.`)
                                    }).catch(() => {
                                        throw new Error('Wrong OTP, try again.')
                                    })
                                }
                            } else {
                                throw new Error('Incorrect OTP. You have exhausted your attempts. Please request a new OTP.')
                            }
                        } else {
                            throw new Error('Incorrect email. How did you get here?')
                        }
                    } else {
                        throw new Error('OTP is expired. Please request a new OTP.')
                    }
                } else {
                    throw new Error('OTP is invalid. Please request a new OTP.')
                }
            }).catch(() => {
                throw new Error('Invalid session id. Please request the OTP through Forgot Password.')
            })
        } else {
            throw new Error('Enter OTP')
        }
    })
})

当我运行该函数时,它会被执行,因为我可以在控制台语句中看到它,但我在客户端遇到以下错误

Access to fetch at 'https://us-central1-project-name.cloudfunctions.net/functionName' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
当我记录从函数收到的响应时,它显示
{“code”:“internal”}

什么是cors包?我如何解决这个问题


第2部分(不相关)

另外,在函数的第11行和第12行,我使用

admin.auth().getUserByEmail(data.email).then(user => {
  admin.auth().updateUser(user.uid, {password: data.password})
})
这是正确的吗


对于第1部分,我提到了这个问题,但它没有答案。

看看可调用云函数的:

  • 您不需要将其封装在返回新承诺中((解析,拒绝)=>{})
  • 需要返回可以JSON编码的数据
  • 需要通过抛出(或返回拒绝的承诺)
    functions.https.HttpsError
    的实例来正确管理错误
  • 需要正确链接异步方法返回的所有承诺
  • 我在下面尝试根据上述要点重新组织您的代码,但由于您的业务逻辑很复杂,我无法对其进行测试,并且可能有其他方法来管理所有案例。。。由你来“抛光”这第一次尝试!希望这会有所帮助

    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 = new Date().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 - 1
                                        return admin.firestore().collection('verification').doc(data.sesId).update({
                                            attempt: redAttempt
                                        })
                                    }
                                } else {
                                    throw new Error('Incorrect OTP. You have exhausted your attempts. Please request a new OTP.')
                                }
                            } else {
                                throw new Error('Incorrect email. How did you get here?')
                            }
                        } else {
                            throw new Error('OTP is expired. Please request a new OTP.')
                        }
                    } else {
                        throw new Error('OTP is invalid. Please request a new OTP.')
                    }
                })
                .then(user => {
                    if(dataOptCorresponds) {
                        return admin.auth().updateUser(user.uid,{
                            password: data.password
                        })
                    } else {
                        throw new Error(`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 => {
                    throw new functions.https.HttpsError('internal', error.message);
    
                })
    
            } else {
    
                throw new functions.https.HttpsError('invalid-argument', 'Enter OTP');
            }
    
    })
    

    更新以下Bergi的评论:

    如果您希望能够区分返回到前端的错误类型(特别是在OTP不正确、无效或过期或电子邮件不正确的情况下发回
    无效参数
    HttpsError
    ),您可以在
    then()
    方法中使用第二个参数

    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 = new Date().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 - 1
                                            return admin.firestore().collection('verification').doc(data.sesId).update({
                                                attempt: redAttempt
                                            })
                                        }
                                    } else {
                                        throw new Error('Incorrect OTP. You have exhausted your attempts. Please request a new OTP.')
                                    }
                                } else {
                                    throw new Error('Incorrect email. How did you get here?')
                                }
                            } else {
                                throw new Error('OTP is expired. Please request a new OTP.')
                            }
                        } else {
                            throw new Error('OTP is invalid. Please request a new OTP.')
                        }
                    },
    
                    error => {
    
                        throw new functions.https.HttpsError('invalid-argument', error.message);
    
                    }
    
                )
                .then(user => {
                    if(dataOptCorresponds) {
                        return admin.auth().updateUser(user.uid,{
                            password: data.password
                        })
                    } else {
                        throw new Error(`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 => {
                    throw new functions.https.HttpsError('internal', error.message);
    
                })
    
            } else {
    
                throw new functions.https.HttpsError('invalid-argument', 'Enter OTP');
            }
    
    })
    

    最后使用
    .catch()
    时,所有
    抛出的
    n错误最终都会成为内部
    HttpsError
    。你需要把它向上移动,否则。@Bergi谢谢你的“提示”!我试着修改答案。如果你能看一看并确认这是正确的方法,那就太好了!然而,我不知道如何实现第二个
    then()
    参数,其中我们有
    if(dataOptCorresponds)
    ,因为错误是
    dataOptCorresponds
    值的函数……噢,忘了我刚才说的。我没有正确阅读您的答案,也没有意识到您实际上希望所有错误消息都包装在
    HttpsError
    中。我想你最初的方法是正确的。伙计们,我真的很感谢你们的帮助,但是因为假期我一周都不在办公桌旁。我会在有机会试用代码后立即回复。@VaibhavJoshi为什么不使用更新3个不同集合中的多个文档?