React App with Firebase Authentication
Tags: firebase, react, signin, signup
Published: 2021-08-29 13:21:41

Today, we will create a simple React App with the functionality of Sign In, Sign Up and Logout and we will integrate our app with firebase cloudstore in order to save the users data.

So, let's begin by creating a new react app by using the command npx create-react-app myApp and do the necessary clean-up after the app has been created which includes removing any test files, logos and commented out code.
Now, let's install firebase in our react app by typing in the command line:
```javascript
npm i firebase
```
Also, you need to navigate to firebase.google.com, create an account (if you don't have one) and. create a new app and then after your project is created, you go to the 'Web' icon, give a name to your app and click 'Register app' after which you will get a block of code, you need to copy that code and create a firebase.js file in the src folder of your react app and paste that code in the following manner:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/45tukwvy0kurjxq5a7nf.png)

Back to the firebase console of your project, you need to click Authentication and then 'Set sign up method', here we will Enable the first option 'Email/Password' and click Save. Please note that 'Users' tab here will show us the list of all the users who have signed up in our application.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5ucrroj65wu0cgvhroei.png)

Now, 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, so in App.js we will define the state variables using the useState hook:
```javascript
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);
```

Now, we will create a 'components' folder in src directory and define a Login.js component there where we will have the Login form (asking for user email and password) and also Sign In/Sign Up buttons:
```javascript
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 handleLogin and handleSignUp functions here but they are missing from our App.js file so let's create them:
```javascript
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:
        }
      });
  };
```

handleLogin function uses the firebase auth() and signInWithEmailAndPassword(email, password) methods to validate the email/password user has entered and throws an error if the information entered is incorrect or not found.

Similarly, we will define the handleSignUp method:
```javascript
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 also define a handleLogout function here which is pretty simple:
```javascript
  const handleLogout = () => {
    firebasedb.auth().signOut();
  };
```
We will also define an authListener() method which will be activated on every auth state change and let us know if a valid user exists on our application:
```javascript
const authListener = () => {
    firebasedb.auth().onAuthStateChanged((user) => {
      if (user) {
        clearInputs();
        setUser(user);
      } else {
        setUser("");
      }
    });
  };
```

Also, we will need a useEffect hook which will call the authListener():
```javascript
useEffect(() => {

    authListener();
  }, []);
```

Now, we need to pass the props in the Login component so that we can import them in our actual component, so in the App.js file, also we will define a Home.js component which will be displayed when the user has logged in, so below we will switch on the basis of 'user' i-e if user exists then we will show the Home component otherwise we will display Login component:
```javascript
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>
  );
```

Also, don' forget to import the props in the Login component:
```javascript
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
```
After, 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, hope you have enjoyed reading..
Happy coding...