Today, we will create a simple React App with the functionality of Sign In, Sign Up, and Logout. We will also integrate our app with Firebase Cloudstore in order to save the user’s data.
Let’s begin by creating a new React App by using the npx create-react-app myApp
command and do the necessary clean-up after the app has been created.
This includes removing any:
Let’s install Firebase in our React App by typing in the command line:
npm i firebase
You also need to navigate to:
After your project is created:
Then, you will get a block of code which you need to copy, and you will create a firebase.js file in the src folder of your React App.
Paste that code in the following manner:
You need to click Authentication and then Set sign up method in the Firebase console of your project. Here, we will enable the first option, Email/Password, and click Save.
Note: The users tab will show us the list of all the users who have signed up in our application.
Let’s go back to our React App and start adding the necessary code to make our app functional. First, we will create state variables for all the states that our app will have. We will define the state variables in App.js using the useState hook:
const [user, setUser] = useState("");
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [emailError, setEmailError] = useState("");
const [passwordError, setPasswordError] = useState("");
const [hasAccount, setHasAccount] = useState(false);
We will create a components folder in src directory and define a login.js component. Here, we will have the login
form (email and password) and also the Sign In
and Sign Up
buttons:
const Login = () => {
return (
<div className="login">
<div className="loginContainer">
<label>Username</label>
<input type="text" autoFocus required value={email} onChange={(e)=> setEmail(e.target.value)}/>
<p className="errorMsg">{emailError}</p>
<label>Password</label>
<input type="password" autoFocus required value={password} onChange={(e)=> setPassword(e.target.value)}/>
<p className="errorMsg">{passwordError}</p>
<div className="btnContainer">
{hasAccount ? (
<>
<button onClick={handleLogin}>Sign In</button>
<p>Don't have an account ? <span onClick={() => setHasAccount(!hasAccount)}>Sign Up</span></p>
</>
) : (
<>
<button onClick={handleSignUp}>Sign Up</button>
<p>Already have an account .. <span onClick={() => setHasAccount(!hasAccount)}>Sign In</span></p>
</>
)}
</div>
</div>
</div>
)
}
export default Login
Notice that we have defined the handleLogin
and handleSignUp
functions here. However, they are missing from our App.js file, so we will have to create them:
const handleLogin = () => {
firebasedb
.auth()
.signInWithEmailAndPassword(email, password)
.catch((err) => {
switch (err.code) {
case "auth/Invalid-email":
case "auth/user-disabled":
case "auth/user-not-found":
setEmailError(err.message);
break;
case "auth/wrong-password":
setPasswordError(err.message);
break;
default:
}
});
};
The handleLogin
function uses the Firebase auth()
and signInWithEmailAndPassword(email, password)
methods to validate the email and password the user has entered. This throws an error if the information entered is incorrect or not found.
Similarly, we will define the handleSignUp
method:
const handleSignUp = () => {
firebasedb
.auth()
.createUserWithEmailAndPassword(email, password)
.catch((err) => {
switch (err.code) {
case "auth/email-already-in-use":
case "auth/invalid-email":
setEmailError(err.message);
break;
case "auth/weak-password":
setPasswordError(err.message);
break;
default:
}
});
};
We will define a handleLogout
function here:
const handleLogout = () => {
firebasedb.auth().signOut();
};
We will also define an authListener()
method, which will be activated on every auth
state change. This will let us know if a valid user exists on our application:
const authListener = () => {
firebasedb.auth().onAuthStateChanged((user) => {
if (user) {
clearInputs();
setUser(user);
} else {
setUser("");
}
});
};
We will need a useEffect hook, which will call the authListener()
:
useEffect(() => {
authListener();
}, []);
login
component:return (
<div className="App">
{user ? (
<Home handleLogout={handleLogout} />
) : (
<Login
email={email}
setEmail={setEmail}
password={password}
setPassword={setPassword}
handleLogin={handleLogin}
handleSignUp={handleSignUp}
hasAccount={hasAccount}
setHasAccount={setHasAccount}
emailError={emailError}
passwordError={passwordError}
/>
)}
</div>
);
Don’t forget to import the
(props)
in thelogin
component:
const Login = (props) => {
const {email, password, setEmail, setPassword, handleLogin, handleSignUp,hasAccount,setHasAccount, emailError, passwordError} = props;
return (
<div className="login">
<div className="loginContainer">
<label>Username</label>
<input type="text" autoFocus required value={email} onChange={(e)=> setEmail(e.target.value)}/>
<p className="errorMsg">{emailError}</p>
<label>Password</label>
<input type="password" autoFocus required value={password} onChange={(e)=> setPassword(e.target.value)}/>
<p className="errorMsg">{passwordError}</p>
<div className="btnContainer">
{hasAccount ? (
<>
<button onClick={handleLogin}>Sign In</button>
<p>Don't have an account ? <span onClick={() => setHasAccount(!hasAccount)}>Sign Up</span></p>
</>
) : (
<>
<button onClick={handleSignUp}>Sign Up</button>
<p>Already have an account .. <span onClick={() => setHasAccount(!hasAccount)}>Sign In</span></p>
</>
)}
</div>
</div>
</div>
)
}
export default Login
Afterward, you will sign up to the application and navigate to your Firebase console. You will see that the list of users will show the user you have just created.
This brings us to the end of our application. Happy coding!