EDIT:对于访问此问题的任何人,请阅读onRequest和onCall函数之间的区别.了解如何在客户端代码中调用它们.了解这里的问题应该会有所帮助.
我正在用firebase为后端构建一个个人项目,并为前端做出react .我正在try 从云函数中正确返回错误.客户端显示的错误不是从服务器发送的错误.我将在下面演示这个问题.
我希望客户端显示一个错误,显示"邮箱地址已被其他帐户使用".从下面的屏幕截图中可以看到,这就是作为响应对象发送的内容.然而,每当我做控制台时.日志(log)(err.message)在客户端显示"无效参数".(请参见下面屏幕截图中的控制台日志(log)).
这是代码.
Cloud functions - index.ts
export const registerUser = https.onRequest((req, resp) => {
cors(req, resp, async () => {
const data = req.body.data;
const userData: IUserData = {
firstName: data.firstName,
lastName: data.lastName,
statusId: 1,
customerId: ''
}
try {
// Create auth user in firebase
const newAuthUser = await admin.auth().createUser({
email: data.email,
emailVerified: false,
password: data.password,
displayName: data.firstName + ' ' + data.lastName,
disabled: false
})
// Create a stripe customer
const uid = newAuthUser.uid;
const stripeCustomer = await createStripeCustomer(data, uid);
userData.customerId = stripeCustomer.id;
// Create user doc in firestore
const storeUserRef = app.firestore().doc('/users/' + uid);
const storeUser = await storeUserRef.set(userData);
resp.status(200).json({
user: storeUser,
message: "User successfully registered"
}).send();
return;
} catch (err: any) {
console.log(err);
resp.status(400).send(err);
return;
}
})
})
React - SignupPage.tsx
function SignUpPage() {
const firebaseAuth = getAuth(FIREBASE_APP);
const functions = getFunctions(FIREBASE_APP);
const [auth, loading] = useAuthState(firebaseAuth);
const [regError, setRegError] = useState("")
const nav = useNavigate();
const { register, handleSubmit, formState: { errors }, } = useForm();
const [registering, setRegistering] = useState(false);
const registerUser = httpsCallable(functions, 'registerUser');
connectFunctionsEmulator(functions, "localhost", 5001);
// Check if a user login exists
useEffect(() => {
// If the auth has finished loading and the user exists, redirect to the
// user account page
if (auth && !loading) { nav('/account') }
}, [auth, loading, nav])
/**
* Form on submit
* @param data
*/
const onSubmit = (data: any) => {
setRegistering(true);
setRegError("");
const userData: IRegisterPayload = {
firstName: data.firstName,
lastName: data.lastName,
email: data.email,
password: data.password
}
registerUser(userData).then(async(res) => {
// return await signInWithEmailAndPassword(
// firebaseAuth, userData.email, userData.password
// );
console.log('REGISTER USER SUCCESS: ', res)
})
.then(res => {
console.log(res);
nav("/account");
})
.catch((err) => {
console.log('Console log err.message:', err.message);
setRegError(err.message);
}).finally(() => {
setRegistering(false);
})
};
return(
<SiteLayout>
<div className="px-3 py-5 mx-auto signup-wrapper w-100 container d-flex flex-column flex-grow-1">
<div className="row">
<div className="col-12 col-lg-6 col-xl-5 pe-lg-5">
<h2 className="h2 mb-4 text-center">Sign up</h2>
<p className="text-center">Already a member? <NavLink to={`/login`}>Login</NavLink></p>
<form onSubmit={handleSubmit(onSubmit)}
className="mb-2"
>
<div className="mb-3">
<label>First Name</label>
<input type={`text`}
className={`form-control${errors.firstName ? ' is-invalid': ''}`}
placeholder="Enter your first name"
disabled={registering}
{...register('firstName', { required: true})}
/>
{errors.firstName && <small className="text-danger d-block mt-1">First Name is required</small>}
</div>
<div className="mb-3">
<label>Last Name</label>
<input type={`text`}
className={`form-control${errors.lastName ? ' is-invalid': ''}`}
placeholder="Enter your last name"
disabled={registering}
{...register('lastName', { required: true})}
/>
{errors.lastName && <small className="text-danger d-block mt-1">Last Name is required</small>}
</div>
<div className="mb-3">
<label>Email</label>
<input type={`email`}
className={`form-control${errors.email ? ' is-invalid': ''}`}
placeholder="Enter your email address"
disabled={registering}
{...register('email', { required: true})}
/>
{errors.email && <small className="text-danger d-block mt-1">Email is required</small>}
</div>
<div className="mb-4">
<label>Password</label>
<input type={`password`}
className={`form-control${errors.password ? ' is-invalid': ''}`}
placeholder="Enter your password"
disabled={registering}
{...register('password',{
required: "You must specify a password",
validate: (val: string) => {
// Check the entered value meets the regex requirement
const isStrong = PASSWORD_REGEX.test(val);
return (val && isStrong) || "Password does not meet criteria";
}
})}
/>
{errors.password && <p className="small text-danger d-block my-1">{errors.password.message}</p>}
<small className="text-muted">Passwords must be a minimum of 8 characters and include:</small>
<ul className="small text-muted">
<li>At least 1 uppercase letter</li>
<li>At least 1 lowercase letter</li>
<li>At least 1 special character</li>
<li>At least 1 number</li>
</ul>
</div>
<Button isLoading={registering}
isSubmit={true}
loadingLabel="Registering..."
className="w-100"
>
Sign up
</Button>
{regError &&
<Message severity="error" text={regError} className="my-3 w-100" />
}
</form>
<p className="small text-muted">
By signing up, you confirm that you accept the Terms of Service and Privacy Policy. This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.
</p>
</div>
</div>
</div>
</SiteLayout>
);
}
export default SignUpPage;
有人能告诉我如何显示我想要的错误消息吗?