# How to use Firebase v9 with React (setup, authentication and CRUD examples)

<div class="lead-paragraph"><span class="dropcap">F</span>irebase v9 takes a modular approach which is different from previous versions. In this post, I'll show you how to use Firebase v9 with React including setup, auth, and CRUD examples.</div><div class="max-w-4xl mx-auto px-4 sm:px-6 pt-4">             <div class="border-t dark:border-slate-700"></div>           </div>

<div class="table-of-contents bg-lightblue dark:bg-transparent rounded-md">
    <div class="font-bold">Quick Nav</div>
    <div class="toc">
    <ol class="toc-list">
<li><a href="#20211130-different">Firebase v9 is Different</a></li>
<li><a href="#20211130-setup">Firebase v9 Setup</a></li>
<li><a href="#20211130-authentication">Firebase v9 Authentication</a></li>
<li><a href="#20211130-crud">Firebase v9 CRUD Examples</a></li>
<li class="subheading"><a href="#20211130-setDoc">setDoc</a></li>
<li class="subheading"><a href="#20211130-addDoc">addDoc</a></li>
<li class="subheading"><a href="#20211130-getDoc">getDoc</a></li>
<li class="subheading"><a href="#20211130-getDocs">getDocs</a></li>
<li class="subheading"><a href="#20211130-updateDoc">updateDoc</a></li>
<li class="subheading"><a href="#20211130-deleteDoc">deleteDoc</a></li>
<li><a href="#20211130-subcollections">Firebase v9 Subcollections</a></li>
<li><a href="#20211130-documentation">Documentation Links</a></li>
    </ol>
    </div>
    </div>

<h2 id="20211130-different">Firebase v9 is Different</h2>

This doesn't mean you should go back to version 8. It means you need to come up to speed with version 9.

And that's what I hope to help you with.

If you are just starting out with Firebase or haven't used it in a while, and you look for tutorials online, 90% of them will leave you confused as they are not version 9.

And version 9 is very different. It's modular whereas version 8 was namespaced.

My aim with this article is **not** how to upgrade your v8 Firebase React project to v9 (you can read all about that <a href="https://firebase.google.com/docs/web/modular-upgrade" target="_blank">here</a> ). Instead, it's aimed at new projects who want to use the latest version of Firebase.

That being said, let's get started.

<h2 id="20211130-setup">Firebase v9 Setup</h2>

The process of creating a new Firebase project and database is the same as always.

1. Go to the <a href="https://console.firebase.google.com/" target="_blank">Firebase Console</a> and click **Add project**.
2. Enter a project name, enable/disable Google Analytics and click create project.
3. Once your project is created Add a "Web App" to your project, name it, then you will be presented with a Firebase config that includes your apiKey, project ID, etc. Copy this to your clipboard and choose "Continue to console."

Your config looks something like this

```javascript
// Import the functions you need from the SDKs you need

// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries

// Your web app's Firebase configuration
const firebaseConfig = {
  apiKey: 'AIzaTyD2Jp9aB7ycUbW1z8QyPLmD111rHezHcOw',
  authDomain: 'delete-project-c7021.firebaseapp.com',
  projectId: 'delete-project-c7021',
  storageBucket: 'delete-project-c7021.appspot.com',
  messagingSenderId: '688102987186',
  appId: '1:688102987186:web:e27537ggg7abc2b86b982b',
};

// Initialize Firebase
const app = initializeApp(firebaseConfig);
```

This configuration deviates from the previous Firebase configs.

Firebase v9 is modular and allows you to import individual features as you need them (which is one of the perks of v9, a much smaller size).

We'll now be calling functions like **_getAuth()_**, **_getFirebase()_**, **_getStorage()_**, etc., and imports now look like the following:

```javascript


```

Pretty neat, yet different.

So create a config file in your project called firestore.js and add the following (using your values of course):

```javascript


const firebaseConfig = {
  apiKey: 'AIzaTyD2Jp9aB7ycUbW1z8QyPLmD111rHezHcOw',
  authDomain: 'delete-project-c7021.firebaseapp.com',
  projectId: 'delete-project-c7021',
  storageBucket: 'delete-project-c7021.appspot.com',
  messagingSenderId: '688102987186',
  appId: '1:688102987186:web:e27537ggg7abc2b86b982b',
};

const app = initializeApp(firebaseConfig);


provider.setCustomParameters({ prompt: 'select_account' });
```

1. We'll import **db** anytime we need to access the database.
2. We'll import **auth** anytime we need to authenticate with Firebase.
3. We'll import **provider** anytime we need to authenticate with Google.

<h2 id="20211130-authentication">Firebase v9 Authentication</h2>

Following our modular approach, to sign in with Google, we'll use our Google provider and the **signInWithPopup()** method (be sure to change the auth and provider import path to match your project).

```javascript


const googleHandler = async () => {
  provider.setCustomParameters({ prompt: 'select_account' });
  signInWithPopup(auth, provider)
    .then((result) => {
      // This gives you a Google Access Token. You can use it to access the Google API.
      const credential = GoogleAuthProvider.credentialFromResult(result);
      const token = credential.accessToken;
      // The signed-in user info.
      const user = result.user;
      // redux action? --> dispatch({ type: SET_USER, user });
    })
    .catch((error) => {
      // Handle Errors here.
      const errorCode = error.code;
      const errorMessage = error.message;
      // The email of the user's account used.
      const email = error.email;
      // The AuthCredential type that was used.
      const credential = GoogleAuthProvider.credentialFromError(error);
      // ...
    });
};
```

To signOut, import the signOut module:

```javascript


signOut(auth)
  .then(() => {
    console.log('logged out');
    navigate('/');
  })
  .catch((error) => {
    console.log(error);
  });
```

That code came directly from the <a href="https://firebase.google.com/docs/auth/web/google-signin" target="_blank">Firebase docs</a>.

For regular username/password, Facebook, Twitter, email link authentication, etc. refer to that page. Each example can be found in the navigation to the left. For example, click <a href="https://firebase.google.com/docs/auth/web/password-auth" target="_blank">Password Authentication</a> to see how to use the username/password authentication.

<h2 id="20211130-crud">Firebase v9 CRUD Examples</h2>

For CRUD functions, again we'll import the modules we need like **getDocs** and **setDoc**, etc.

Here are some examples using Notes as an example:

\*_Note how you are importing/using doc and collection depending on whether you want a document or a collection_

<h3 id="20211130-setDoc">setDoc</h3>

setDoc is used to create a document when you have a meaningful ID that you want to use. You must specify an ID.

```javascript


  await setDoc(doc(db, 'notes', note.id), note);
};
createNote(note);
```

<h3 id="20211130-addDoc">addDoc</h3>

Sometimes you do not have a meaningful ID that you want to use and thus want Firestore to create a unique one for you. For this, you use addDoc.

```javascript


  await addDoc(collection(db, 'notes'), coin);
};
createNote(note);
```

<h3 id="20211130-getDoc">getDoc</h3>

```javascript


  const noteSnapshot = await getDoc(doc(db, 'notes', id));
  if (noteSnapshot.exists()) {
    return noteSnapshot.data();
  } else {
    console.log("Note doesn't exist");
  }
};
getNote(id);
```

<h3 id="20211130-getDocs">getDocs</h3>
```javascript


const notesSnapshot = await getDocs(collection(db, "notes"));
const notesList = notesSnapshot.docs.map((doc) => doc.data());
return notesList;
};
getNotes();

````

<h3 id="20211130-updateDoc">updateDoc</h3>

To update some of the fields without overwriting the entire document, use updateDoc().

```javascript


    const noteRef = doc(db, "notes", note.id);
    await updateDoc(noteRef, {
        excerpt: "New description"
    });
};
updateNote(note);

````

<h3 id="20211130-deleteDoc">deleteDoc</h3>

```javascript


  const noteRef = doc(db, 'notes', note.id);
  await deleteDoc(noteRef);
};
deleteNote(note);
```

<h2 id="20211130-subcollections">Firebase v9 Subcollections</h2>

What about subcollections and their documents? How do we go that deep?

Well, let's say we have different sets of notes.

So there is a collection of sets and within that are 'sets' documents (like set 1, set 2, etc).

Then within each document is a collection of notes. It looks something like this:

| collection | documents (sets) | subcollections | documents (notes)   |
| ---------- | ---------------- | -------------- | ------------------- |
| sets       | set 1            | notes          | note 1, note 2, etc |
|            | set 2            | notes          | note 1, note 2, etc |
|            | set 3            | notes          | note 1, note 2, etc |

How do you access those documents in the subcollection (note 1, note 2, etc)?

You use getDocs, but add another parameter of the subcollection added.

So to get the notes within set 1, you could do something like:

```javascript


    const subcollections = await getDocs(collection(db, 'sets', setId, 'notes'));
    subcollection.forEach((doc) => {
        console.log(doc.data());
    });
}
getSubCollections('set 1')
```

<h2 id="20211130-documentation">Documentation Links</h2>

**CRUD Documentation** - <a href="https://firebase.google.com/docs/firestore/manage-data/add-data" target="_blank">Firebase CRUD Docs</a>. (Be sure to choose version 9 in the code examples tabs and other data management functions like adding, reading, batching, compound queries, etc. can be found in the navigation to the left.)

**Auth documentation** - <a href="https://firebase.google.com/docs/auth/web/google-signin" target="_blank">Firebase Auth Docs</a>. (Same applies, different auth examples in the nav to the left.)