Updating User Profile Using React and Firebase
Tags: react, javascript
Published: 2020-07-20 03:44:48

In a previous post, I shared the steps I took to wire a React project to connect to Firebase services and retrieve data from the database.
{% link clarkj99/fetching-from-firestore-realtime-database-38g %}

My latest task involved creating a user with the Firebase Auth service and persisting profile data for the user.

The user was created through a React component containing a form for signup.  When submitted, the form executes the function `loginUser()`.

```javascript
  const loginUser = () => {
    props.firebase
      .doCreateUserWithEmailAndPassword(inputs)
      .then((authUser) => {
        console.log("authUser: ", authUser);
      })
      .catch((error) => {
        console.error(error.code, error.message);
      });
  };
```
The fields from the form are passed to the Firebase handler function.

In my project, the connections to the Firebase services and helper methods are encapsulated in a class.  In my project, the file is `/src/Firebase/firebase.js`.

```javascript
class Firebase {
  constructor() {
    app.initializeApp(firebaseConfig);
    this.auth = app.auth();
    this.db = app.firestore();
  }

...

}
```
The form fields are passed to the `doCreateUserWithEmail()` method.  This method relies on the `createUserWithEmailAndPassword()` and `updateProfile()` methods supplied by the Firebase library.

Firebase Auth Class maintains a basic set of fields for the display_name, email, phone_number, and uid (unique identifier).  All other fields must be stored separately in a database like Firestore. In my case, they are stored in a Firestore collection called `users`.

The action takes place asynchronously through Promise chains.  First, the authorized user is created. Then a default display_name is derived from the email address and persisted in the Auth record.  Finally, a `users` document is created with the `uid` as the key, and the fields from `inputs` as data. In this example, I'm saving the first and last names.

```javascript
  doCreateUserWithEmailAndPassword = (inputs) => {
    const { email, password, firstName, lastName } = inputs;

    return this.auth
      .createUserWithEmailAndPassword(email, password)
      .then((user) => {
        const displayName = user.user.email.split("@")[0];
        return this.auth.currentUser.updateProfile({ displayName });
      })
      .then(() => {
        console.log(this.auth.currentUser);
        return this.db
          .collection("users")
          .doc(this.auth.currentUser.uid)
          .set({ firstName, lastName });
      })
      .catch((error) => console.error("Error: ", error));
  };
```
The profile document for a single user can easily be retrieved from the `users` collection by referencing the `uid`.
```javascript
  doGetUserProfile = (uid, callback) => {
      return this.db
          .collection("users")
          .doc(uid)
          .get()
          .then(callback);
  };
```
Similarly, the profile document for an existing user can easily be updated.

```javascript
 doProfileUpdate = (profile) => {
    return this.db
      .collection("users")
      .doc(this.auth.currentUser.uid)
      .set(profile)
      .catch((error) => console.error("Error: ", error));
  };
```
So far, my foray into Firebase has been quite rewarding. It's easy to see that after a few implementations the development time for my applications will begin to diminish.

Happy coding!

<span>Cover photo by <a href="https://unsplash.com/@kellysikkema?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Kelly Sikkema</a> on <a href="https://unsplash.com/s/photos/user?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></span>