I want to create a login page that only a user of type admin can access. I have a field in my user's collection called level, and if the level is equal to admin the user should be able to log in otherwise they cant.
here is what I have tried so far but it is not working properly.
is there a better way to achieve what I require, or can my method be improved to be working properly? how can I query and authenticate the admin user using firestore?
const Login = () => {
const navigate = useNavigate();
const [adminEmail,setAdminEmail] = useState("")
const [adminPassword,setAdminPassword] = useState("")
const [adminFBEmail,setAdminFBEmail] = useState("")
const [adminFBPassword,setAdminFBPassword] = useState("")
useEffect(() => {
firebase.firestore().collection("Users").get().then((adminSnapshot) => {
adminSnapshot.forEach((doc) => {
if(doc.data().level != "admin"){
alert("not admin")
}else{
setAdminFBEmail(doc.data().email)
setAdminFBPassword(doc.data().password)
}
})
})
},[]);
const handleSubmit = () => {
if(adminEmail == adminFBEmail && adminPassword == adminFBPassword){
alert("Admin logged in")
navigate('/app/dashboard', { replace: true });
}else{
alert("error")
}
}
return (
<>
<Helmet>
<title>Login | Power Cargo</title>
</Helmet>
<Box
sx={{
backgroundColor: 'background.default',
display: 'flex',
flexDirection: 'column',
height: '100%',
justifyContent: 'center'
}}
>
<Container maxWidth="sm">
<Formik
initialValues={{
email: '',
password: ''
}}
validationSchema={Yup.object().shape({
email: Yup.string().email('Must be a valid email').max(255).required('Email is required'),
password: Yup.string().max(255).required('Password is required')
})}
onSubmit={() => {
}}
>
{({
errors,
handleBlur,
handleChange,
isSubmitting,
touched,
values
}) => (
<form onSubmit={handleSubmit} >
<Box sx={{ mb: 3 }}>
<Typography
color="textPrimary"
variant="h2"
>
Sign on the internal platform
</Typography>
</Box>
<TextField
error={Boolean(touched.email && errors.email)}
fullWidth
helperText={touched.email && errors.email}
label="Email Address"
margin="normal"
name="email"
onBlur={handleBlur}
onChange={(e)=> {
setAdminEmail(e.target.value)}}
type="email"
variant="outlined"
/>
<TextField
error={Boolean(touched.password && errors.password)}
fullWidth
helperText={touched.password && errors.password}
label="Password"
margin="normal"
name="password"
onBlur={handleBlur}
onChange={(e)=> {
setAdminPassword(e.target.value)}}
type="password"
variant="outlined"
/>
<Box sx={{ py: 2 }}>
<Button
color="primary"
disabled={isSubmitting}
fullWidth
size="large"
type="submit"
variant="contained"
onClick={handleSubmit}
>
Sign in now
</Button>
</Box>
</form>
)}
</Formik>
</Container>
</Box>
</>
);
}
CodePudding user response:
Please please please don't implement your own email password check, as there are dozens (if not hundreds) of pitfalls and you're likely hit many of them if you've never done this before. Instead use a dedicated provider for that - such as the one in Firebase Authentication.
You can then still store the information about what user is an Admin in your Firestore database, but you'd do that by associating the user's ID (the UID from Firebase Authentication) with a role in the database. For more on this type of system, see some of the previous questions on the topic: