Project 54 of 100 - User Sign Up with Firebase
Tags: react, 100daysofcode, javascript
Published: 2021-03-05 07:17:01

*Hey! I'm on a mission to make 100 React.js projects ending March 31st. Please follow my dev.to profile or my [twitter](https://www.twitter.com/jwhubert91) for updates and feel free to reach out if you have questions. Thanks for your support!*

Link to the deployed project: [Link](https://react-firebase-15.web.app/)
Link to the repo: [github](https://github.com/jwhubert91/100daysofreact/tree/master/day-54-firebase-sign-up)

So this project started as an ambitious Twitter clone, but as it got late settled into just a UI with sign up. Writing custom CSS takes forever so that always takes up the bulk of the time in these projects. All of that said, for someone new to Firebase it is great to just practice the auth flow.

Here are the major parts of creating a user sign up flow with Firebase.

###Step 1. Sign Up for Firebase
Go to the Firebase console. Sign up for an account if you don't have one, then create a new Firebase project in the console and make sure you choose "Web" for the project type. You can choose Google Analytics if you want, but it's not necessary. Finally, copy the config object they show you- these are your important API details to interact with Firebase. They will look something like this:

```JS
const firebaseConfig = {
  apiKey: "AIsw94lKzaSyCVhNKXMlogVIYUjuQ4K_xxxxx",
  authDomain: "your-app-name.firebaseapp.com",
  projectId: "your-app-name",
  storageBucket: "your-app-name.appspot.com",
  messagingSenderId: "xxxxxx",
  appId: "1:561364346658:web:a28810561a0b0a4ce1d49b"
};
```

...You can also now activate Authentication by clicking the Auth button in your project's Firebase Console then click "Get Started" and choose your preferred sign up method.

###2. Create your Project
Create a new React project and then install the Firebase node module with `npm i firebase`. Within the /src folder create a file called `firebase.js`. Here you can store the config details you just copied. You should also initialize the connection to the authentication system here. For me this code looks something like the following:

```JS
import firebase from 'firebase';

// this is the piece from before:
const firebaseConfig = {
  apiKey: "AIsw94lKzaSyCVhNKXMlogVIYUjuQ4K_xxxxx",
  authDomain: "your-app-name.firebaseapp.com",
  projectId: "your-app-name",
  storageBucket: "your-app-name.appspot.com",
  messagingSenderId: "xxxxxx",
  appId: "1:561364346658:web:a28810561a0b0a4ce1d49b"
};

const firebaseApp = firebase.initializeApp(firebaseConfig);

const db = firebaseApp.firestore();
const auth = firebase.auth();

export { db, auth };
```

###3. Set Up Your Component
The following can take place in any component, but I wanted to do everything in `App.js` so that's where I have my form. The bare minimum you'll need to sign up a new user are two text inputs for an email and a password, and of course in React you'll need to pieces of state for this. I do this using `useState` in a functional component but you could of course use a class component.

When you're ready to sign up your user create a submit function for the form and make sure you call `e.preventDefault()` at the top of that function or the page will follow the html form submission default action and refresh the page.

```JS
  const handleSignUp = (e) => {
    e.preventDefault();
  }
```

###4. Create the user in Firebase
Firebase is much loved by developers in part because it rolls authentication for you. We can create a new user using your two pieces of state for username and password and the following pre-built method that calls the Firebase `auth` module:

```JS
 auth.createUserWithEmailAndPassword(username,password)
```

In my application I also add a username to the user's profile information on sign up. Firebase calls this username a `displayName`. You can see in that function in my application how I am able to set the displayName in the `.then()` method returned by the promise of the above pre-built Firebase method. Here's that function in its entirety:

```JS
  const handleSignUp = (e) => {
    e.preventDefault();
    if (user) return auth.signOut();
    auth.createUserWithEmailAndPassword(email,password)
      .then(() => {
        const user = auth.currentUser;
        user.updateProfile({
          displayName: username
        })
      })
      .catch((error) => alert(error.message));

    setEmail('');
    setUsername('');
    setPassword('');
    ...
  }
```

Since the entire process is asynchronous, we have to actually call `auth.currentUser` to get the current user data and store it in a variable in the above callback. 

I also set the `displayName` of the user's profile in the database using the `user.updateProfile()` method which is also pre-built. This method exists because in Firebase, user information exists in its own special users database so we have pre-built functions to interact with that specific database, which is part of the Auth system.

###5. Use `useEffect` to Detect the New User
The following function is a piece of beauty. Firebase's Auth package comes with its own ability to store user data in your cookies. The pre-built method to query Firebase's Auth system and see if there is a signed in user is the following:

```JS
auth.onAuthStateChanged()
```

This method takes a callback function for an argument that we can use to make changes in our app when there is a change in the signed in user, or if there is no signed in user. Since this could make changes to how our component is rendered, we should put it in a `useEffect` function.

In my callback, I make use of a `user` state variable and store the signed in user there if the `onAuthStateChanged` listener changes, or store `null` if there is no signed in user anymore. Remember that this will make changes to the component so you'll need to actually unsubscribe to the effect when the operation completes, usually in the `return` statement. Mine looks like this:

```JS
  useEffect(() => {
    const unsubscribe = auth.onAuthStateChanged((authUser) => {
      if (authUser) {
        // a user is logged in
        setUser(authUser);
      } else {
        // there is no logged in user
        setUser(null);
      }
    })
    return () => {
      // perform some cleanup actions before firing useEffect
      console.log(user);
      unsubscribe();
    }
  },[user])
```

We store a reference to the `user` state in the brackets for our `useEffect` call because we want this function to run again everytime the user state changes in our component (this would indicate someone signed up or signed out).

That's it! That's all you need to sign up a user in Firebase. Enjoy.