{"id":2269,"date":"2022-01-25T18:26:37","date_gmt":"2022-01-25T18:26:37","guid":{"rendered":"https:\/\/lvboard.infostore.in.ua\/?p=2269"},"modified":"2022-01-25T18:26:37","modified_gmt":"2022-01-25T18:26:37","slug":"build-a-crud-application-in-react-with-firebase-web-sdk-v9","status":"publish","type":"post","link":"https:\/\/lvboard.infostore.in.ua\/?p=2269","title":{"rendered":"Build a CRUD application in React with Firebase Web SDK v9"},"content":{"rendered":"\n<p>The&nbsp;<a href=\"https:\/\/firebase.googleblog.com\/2021\/08\/deep-dive-into-the-new-firebase-js-sdk-design.html\" target=\"_blank\" rel=\"noreferrer noopener\">Firebase v.9 SDK<\/a>&nbsp;introduces a new API surface that follows a modular approach, resulting in a change to the use of its services, one of which is&nbsp;<a href=\"https:\/\/firebase.google.com\/docs\/firestore\" target=\"_blank\" rel=\"noreferrer noopener\">Firestore database<\/a>. Now we are left with the challenge of relearning how to perform operations like CRUD in the database.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p>In this tutorial, we\u2019ll cover how to carry out CRUD operations in Firestore by building a task manager.<\/p>\n\n\n\n<p>You can&nbsp;<a href=\"https:\/\/tammibriggs-task-manager.netlify.app\/\" target=\"_blank\" rel=\"noreferrer noopener\">view the demo app here<\/a>. The code for this tutorial is available on&nbsp;<a href=\"https:\/\/github.com\/Tammibriggs\/Task-manager\" target=\"_blank\" rel=\"noreferrer noopener\">GitHub<\/a>.<\/p>\n\n\n\n<p>To follow along with this tutorial, you should be familiar with&nbsp;<a href=\"https:\/\/blog.logrocket.com\/tag\/react\/\" target=\"_blank\" rel=\"noreferrer noopener\">React<\/a>,&nbsp;<a href=\"https:\/\/blog.logrocket.com\/underrated-react-hooks-youre-missing-out-on\/\" target=\"_blank\" rel=\"noreferrer noopener\">React Hooks<\/a>, and&nbsp;<a href=\"https:\/\/firebase.google.com\/support\/releases\" target=\"_blank\" rel=\"noreferrer noopener\">Firebase v8<\/a>. You should also have Node.js installed on your machine.<\/p>\n\n\n\n<h2>Setting up Firestore<\/h2>\n\n\n\n<p>Before we can start using the Firestore service, we need to first create a project and a database on Firebase.<\/p>\n\n\n\n<h3>Add a project<\/h3>\n\n\n\n<p>Projects in Firebase are containers for our app. It lets us share data and analytics across platforms (e.g., Android, iOS, and web) so users have the same experience regardless of the device they\u2019re on.<\/p>\n\n\n\n<p>To add a project, make sure you\u2019re logged into your Google account, then navigate to&nbsp;<a href=\"https:\/\/console.firebase.google.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">Firebase console<\/a>&nbsp;and click&nbsp;<strong>Add project<\/strong>. We should see a page like this:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2021\/12\/firebase-console-dashboard.png\" alt=\"Firebase Console Dashboard\" class=\"wp-image-84009\"\/><\/figure><\/div>\n\n\n\n<p>Enter the project name \u2014 for this tutorial, we\u2019ll call it \u201ctask-manager,\u201d then accept the Firebase terms and click&nbsp;<strong>Continue<\/strong>. We\u2019ll be prompted to enable Google Analytics. We don\u2019t need Google Analytics for this tutorial, but leaving it on won\u2019t do any harm.<\/p>\n\n\n\n<p>Once all the steps to add the project have been completed we will be redirected to our project page:<a href=\"https:\/\/blog.logrocket.com\/build-crud-application-react-firebase-web-sdk-v9\/\"><\/a><\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2021\/12\/firebase-project-page.png\" alt=\"Firebase Project Page\" class=\"wp-image-84012\"\/><\/figure><\/div>\n\n\n\n<p>With this, we have successfully created our Firebase project.<\/p>\n\n\n\n<h3>Create a database<\/h3>\n\n\n\n<p>On the sidebar, click the&nbsp;<strong>Firestore database<\/strong>&nbsp;icon to navigate to the Cloud Firestore page.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2021\/12\/cloud-firestore.png\" alt=\"Cloud Firestore\" class=\"wp-image-84014\"\/><\/figure><\/div>\n\n\n\n<p>Click the&nbsp;<strong>Create database<\/strong>&nbsp;button and a prompt will appear asking to start the database in production or test mode.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2021\/12\/create-database-page.png\" alt=\"Create Database Page\" class=\"wp-image-84016\"\/><\/figure><\/div>\n\n\n\n<p>Choose&nbsp;<strong>Start in test mode<\/strong>&nbsp;and click&nbsp;<strong>Next<\/strong>. Then, on the next screen, click&nbsp;<strong>Enable.<\/strong>&nbsp;Once these steps have been completed, an empty database will be created for us.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2021\/12\/cloud-firestore-data-tab.png\" alt=\"Cloud Firestore Data Tab\" class=\"wp-image-84018\"\/><\/figure><\/div>\n\n\n\n<h2>Setting up React<\/h2>\n\n\n\n<p>I already created a task manager template so we can solely focus on adding CRUD functionalities.<\/p>\n\n\n\n<p>The next step is to clone the GitHub repo. We can do this with the following commands:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ git clone -b starter https:\/\/github.com\/Tammibriggs\/Task-manager.git\n\n$ cd Task-manager\n\n$ npm install<\/pre>\n\n\n\n<p>In the starter repo we cloned, I also included&nbsp;<code>\"firebase\":&nbsp;\"9.5.0\"<\/code>&nbsp;in the dependency object of the&nbsp;<code>package.json<\/code>&nbsp;file. So by running the&nbsp;<code>npm install<\/code>&nbsp;command, Firebase v9, along with all other dependencies, will be installed.<\/p>\n\n\n\n<p>Now when we start the app with&nbsp;<code>$ npm start<\/code>, we should see this page in our browser:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2021\/12\/task-manager.png\" alt=\"Task Manager\" class=\"wp-image-84020\"\/><\/figure><\/div>\n\n\n\n<p>Feel free to go through the app to get a feel for what we will be working on.<\/p>\n\n\n\n<h2>Integrating Firebase into our React app<\/h2>\n\n\n\n<p>To integrate Firebase into our React app, we need to first get the web configuration object and then use it to initialize Firebase in our react app.<\/p>\n\n\n\n<p>On our Firebase project page, we should see a couple of icons:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2021\/12\/firebase-icons.png\" alt=\"Firebase Icons\" class=\"wp-image-84022\"\/><\/figure><\/div>\n\n\n\n<p>Click the web (<strong>&lt;\/&gt;<\/strong>) icon to configure the Firebase project for the web. We should see a page like this:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2021\/12\/firebase-register-page.png\" alt=\"Firebase Register Page\" class=\"wp-image-84024\"\/><\/figure><\/div>\n\n\n\n<p>Give the web app a name. For this tutorial, we\u2019ll name it&nbsp;<strong>task-manager<\/strong>. Click the&nbsp;<strong>Register app<\/strong>&nbsp;button to move on to the next step, in which our&nbsp;<code>firebaseConfig<\/code>&nbsp;object is revealed to us:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2021\/12\/firebaseconfig-object.png\" alt=\"Firebaseconfig Object\" class=\"wp-image-84026\"\/><\/figure><\/div>\n\n\n\n<p>Copy the config to the clipboard; we\u2019ll need it later on to initialize Firebase. Then, click&nbsp;<strong>Continue to console<\/strong>&nbsp;to complete the process.<\/p>\n\n\n\n<p>Now, let\u2019s initialize Firebase so we can start using Firestore in our app.<\/p>\n\n\n\n<p>In the&nbsp;<code>src<\/code>&nbsp;directory of our React app, create a&nbsp;<code>firebase.js<\/code>&nbsp;file and add the following imports:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ JavaScript\n\/\/ src\/firebase.js\nimport { initializeApp } from \"firebase\/app\"\nimport { getFirestore } from \"firebase\/firestore\"<\/pre>\n\n\n\n<p>Now, paste the config we copied earlier after the imports and add the following lines of code to initialize Firebase and Firestore:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ JavaScript\n\/\/ src\/firebase.js\nconst app = initializeApp(firebaseConfig)\nconst db = getFirestore(app)\n\nexport {db}<\/pre>\n\n\n\n<p>Our&nbsp;<code>firebase.js<\/code>&nbsp;file should now look something like this:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ JavaScript\n\/\/ src.firebase.js\nimport { initializeApp } from \"firebase\/app\"\nimport { getFirestore } from \"firebase\/firestore\"\n\nconst firebaseConfig = {\n  apiKey: \"API_KEY\",\n  authDomain: \"AUTH_DOMAIN\",\n  projectId: \"PROJECT_ID\",\n  storageBucket: \"STORAGE_BUCKET\",\n  messagingSenderId: \"MESSAGING_SENDER_ID\",\n  appId: \"APP_ID\"\n}\n\n\/\/ Initialize Firebase and Firestore\nconst app = initializeApp(firebaseConfig)\nconst db = getFirestore(app)\nexport {db}<\/pre>\n\n\n\n<p>We can now start using Firestore in our app.<\/p>\n\n\n\n<h2>Example: Building a task manager in React with Firebase<\/h2>\n\n\n\n<p>Since we already have a template for the task manager app, we\u2019ll focus on implementing the CRUD functionalities, which are:<\/p>\n\n\n\n<ul><li>Adding a new task to Firestore<\/li><li>Getting all tasks from Firestore<\/li><li>Updating a task<\/li><li>Deleting a task<\/li><\/ul>\n\n\n\n<h3>Add a new task to Firestore<\/h3>\n\n\n\n<p>A task in our app contains a&nbsp;<code>title<\/code>,&nbsp;<code>description<\/code>, and a&nbsp;<code>checkbox<\/code>&nbsp;that will be used to determine whether a task is complete. So to add a new task, we need to create a document in Firestore that contains these fields.<\/p>\n\n\n\n<p>In Firebase v9, we can use the&nbsp;<code>addDoc<\/code>&nbsp;or&nbsp;<code>setDoc<\/code>&nbsp;function to add a new document. This is similar to&nbsp;<code>add<\/code>&nbsp;and&nbsp;<code>set<\/code>&nbsp;in Firebase v8. However, since we want each document to use an autogenerated ID, we will use the&nbsp;<code>addDoc<\/code>&nbsp;function.<\/p>\n\n\n\n<p>In the&nbsp;<code>src<\/code>&nbsp;directory, go over the&nbsp;<code>AddTask.js<\/code>&nbsp;file and add the following imports:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ JavaScript\n\/\/ src\/AddTask.js\nimport {db} from '.\/firebase'\nimport {collection, addDoc, Timestamp} from 'firebase\/firestore'<\/pre>\n\n\n\n<p>Here, we have imported&nbsp;<code>db<\/code>, a Firestore instance,&nbsp;<code>collection<\/code>, which will be used to create a reference to all our tasks, the&nbsp;<code>addDoc<\/code>&nbsp;function, and&nbsp;<code>Timestamp<\/code>&nbsp;for setting the time a task is created.<\/p>\n\n\n\n<p>Now let\u2019s use these functions we have imported to create the functionality for adding new tasks to Firestore. Add the following lines of code after the&nbsp;<code>\/*function to add new task to firestore*\/<\/code>&nbsp;comment:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ JavaScript\n\/\/ src\/AddTask.js\n...\n\/* function to add new task to firestore *\/\nconst handleSubmit = async (e) =&gt; {\n   e.preventDefault()\n   try {\n     await addDoc(collection(db, 'tasks'), {\n       title: title,\n       description: description,\n       completed: false,\n       created: Timestamp.now()\n     })\n     onClose()\n   } catch (err) {\n     alert(err)\n   }\n }\n...<\/pre>\n\n\n\n<p>Here, we created an asynchronous function that adds a new document to a&nbsp;<code>tasks<\/code>&nbsp;collection using&nbsp;<code>addDoc<\/code>. The newly created document will have a title and description field, whose values are obtained from the state; a completed field, which we\u2019ll set to be either true or false based on whether a task has been completed; and a created field, setting its value as the time the new document was added to the database.<\/p>\n\n\n\n<p>For this functionality to start working, we have to call the&nbsp;<code>handleSubmit<\/code>&nbsp;function when the&nbsp;<code>addTask<\/code>&nbsp;form is submitted.<\/p>\n\n\n\n<p>To do this, modify the opening tag of the&nbsp;<code>addTask<\/code>&nbsp;form to look like this:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ JavaScript\n\/\/ src\/AddTask.js\n&lt;form onSubmit={handleSubmit} className='addTask' name='addTask'&gt;<\/pre>\n\n\n\n<p>That\u2019s it! We\u2019re now able to add new tasks to the database. To test this, in our task manager app, click on the&nbsp;<strong>Add Task +<\/strong>&nbsp;button and fill in the form.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2021\/12\/add-task.png\" alt=\"Add Task\" class=\"wp-image-84028\"\/><\/figure><\/div>\n\n\n\n<p>Then, click&nbsp;<strong>Done<\/strong>. Since we have not replaced our mockup data with the one from Firestore, our app UI will not change. But when we go over to Cloud Firestore in the Firebase project we created earlier, we\u2019ll see that a&nbsp;<code>tasks<\/code>&nbsp;collection and a new document has been added.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2021\/12\/tasks-collection.png\" alt=\"Tasks Collection\" class=\"wp-image-84030\"\/><\/figure><\/div>\n\n\n\n<h3>Get all tasks in real time<\/h3>\n\n\n\n<p>We can accomplish this in Firebase v9 by using the&nbsp;<code>onSnapshot<\/code>&nbsp;function. This function takes in two arguments. The first argument can either be a reference to a collection or document or it can be a query. The second argument is a callback that returns a snapshot of the database in real time.<\/p>\n\n\n\n<p>Now, let\u2019s use this function to listen to the&nbsp;<code>tasks<\/code>&nbsp;collection in real time.<\/p>\n\n\n\n<p>In the&nbsp;<code>src<\/code>&nbsp;directory, go over to the&nbsp;<code>TaskManager.js<\/code>&nbsp;file and add the following imports:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ JavaScript\n\/\/ src\/TaskManager\nimport {useState, useEffect} from 'react'\nimport {collection, query, orderBy, onSnapshot} from \"firebase\/firestore\"\nimport {db} from '.\/firebase'<\/pre>\n\n\n\n<p>Next, let\u2019s create a state that will hold all the tasks received from the database. Add the following line of code after the&nbsp;<code>openAddModal<\/code>&nbsp;state:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ JavaScript\n\/\/ src\/TaskManager\n....\nconst [openAddModal, ...\nconst [tasks, setTasks] = useState([])\n\n...<\/pre>\n\n\n\n<p>Now, let\u2019s add a&nbsp;<code>useEffect<\/code>, which will call the&nbsp;<code>onSnapshot<\/code>&nbsp;function when the component is mounted. Add the following lines of code after the&nbsp;<code>\/* function to get all tasks from firestore in realtime *\/<\/code>&nbsp;comment:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ JavaScript\n\/\/ src\/TaskManager.js\n...\n\n\/* function to get all tasks from firestore in realtime *\/\nuseEffect(() =&gt; {\n  const q = query(collection(db, 'tasks'), orderBy('created', 'desc'))\n  onSnapshot(q, (querySnapshot) =&gt; {\n    setTasks(querySnapshot.docs.map(doc =&gt; ({\n      id: doc.id,\n      data: doc.data()\n    })))\n  })\n},[])\n\n...<\/pre>\n\n\n\n<p>Firebase v9 exposes a new function called&nbsp;<code>query<\/code>, which is used to specify which documents we want to retrieve from a collection or collection group.<\/p>\n\n\n\n<p>In the above code, we used the&nbsp;<code>query<\/code>&nbsp;function to specify that we want to retrieve all the documents in the&nbsp;<code>tasks<\/code>&nbsp;collection in descending order of when they were created using the&nbsp;<code>orderBy<\/code>&nbsp;function. We passed the query to the&nbsp;<code>onSnapshot<\/code>&nbsp;function, which returns a&nbsp;<code>querySnapshot<\/code>&nbsp;that was mapped and stored in the&nbsp;<code>task<\/code>&nbsp;state.<\/p>\n\n\n\n<p>Now, let\u2019s replace our mockup data with the one we got from Firestore. At the bottom of the&nbsp;<code>TaskManager.js<\/code>&nbsp;component, replace the two&nbsp;<code>Task<\/code>&nbsp;components we rendered with the following lines of code:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ JavaScript\n\/\/ src\/TaskManager.js\n...\n{tasks.map((task) =&gt; (\n  &lt;Task\n    id={task.id}\n    key={task.id}\n    completed={task.data.completed}\n    title={task.data.title} \n    description={task.data.description}\n  \/&gt;\n))}\n...<\/pre>\n\n\n\n<p>After adding the above code, the&nbsp;<code>TaskManager.js<\/code>&nbsp;file will look like this:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ JavaScript\n\/\/ src\/TaskManager.js\nimport '.\/taskManager.css'\nimport Task from '.\/Task'\nimport AddTask from '.\/AddTask'\nimport {useState, useEffect} from 'react'\nimport {collection, query, orderBy, onSnapshot} from \"firebase\/firestore\"\nimport {db} from '.\/firebase'\n\nfunction TaskManager() {\n  const [openAddModal, setOpenAddModal] = useState(false)\n  const [tasks, setTasks] = useState([])\n\n  \/* function to get all tasks from firestore in realtime *\/ \n  useEffect(() =&gt; {\n    const q = query(collection(db, 'tasks'), orderBy('created', 'desc'))\n    onSnapshot(q, (querySnapshot) =&gt; {\n      setTasks(querySnapshot.docs.map(doc =&gt; ({\n        id: doc.id,\n        data: doc.data()\n      })))\n    })\n  },[])\n\n  return (\n    &lt;div className='taskManager'&gt;\n      &lt;header&gt;Task Manager&lt;\/header&gt;\n      &lt;div className='taskManager__container'&gt;\n        &lt;button \n          onClick={() =&gt; setOpenAddModal(true)}&gt;\n          Add task +\n        &lt;\/button&gt;\n        &lt;div className='taskManager__tasks'&gt;\n        {tasks.map((task) =&gt; (\n          &lt;Task\n            id={task.id}\n            key={task.id}\n            completed={task.data.completed}\n            title={task.data.title} \n            description={task.data.description}\n          \/&gt;\n        ))}\n        &lt;\/div&gt;\n      &lt;\/div&gt;\n      {openAddModal &amp;&amp;\n        &lt;AddTask onClose={() =&gt; setOpenAddModal(false)} open={openAddModal}\/&gt;\n      }\n    &lt;\/div&gt;\n  )\n}\n\nexport default TaskManager<\/pre>\n\n\n\n<p>Now, when we go to our task manager app, we\u2019ll notice that the task we added earlier to Firestore is displayed.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2021\/12\/complete-react-build.png\" alt=\"Complete React Build\" class=\"wp-image-84032\"\/><\/figure><\/div>\n\n\n\n<h3>Update&nbsp;a task in Firestore<\/h3>\n\n\n\n<p>In our app, a task can be updated in two ways. One is by editing the title or description of the task and the other is by clicking the checkbox signifying a task has been completed.<\/p>\n\n\n\n<p>The Firstore function we\u2019ll use for this is the&nbsp;<code>updateDoc<\/code>&nbsp;function. This function will allow us to update some fields of a document without overwriting the entire document. It takes in two arguments: the first is a reference to the document being updated and the second is the updates to be made to the document fields.<\/p>\n\n\n\n<p>Let\u2019s start by creating the functionality to update the task title and description. In the&nbsp;<code>src<\/code>, go over to the&nbsp;<code>EditTask.js<\/code>&nbsp;file and add the following imports:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ JavaScript\n\/\/ src\/EditTask.js\nimport { doc, updateDoc } from \"firebase\/firestore\";\nimport {db} from '.\/firebase'\n<\/pre>\n\n\n\n<p>Next, we\u2019ll add a function that will invoke the&nbsp;<code>updateDoc<\/code>&nbsp;function when it is called. Add the following line of code after the&nbsp;<code>\/* function to update document in firestore *\/<\/code>&nbsp;comment:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ JavaScript\n\/\/ src\/EditTask.js\n...\n\/* function to update document in firestore *\/\nconst handleUpdate = async (e) =&gt; {\n  e.preventDefault()\n  const taskDocRef = doc(db, 'tasks', id)\n  try{\n    await updateDoc(taskDocRef, {\n      title: title,\n      description: description\n    })\n    onClose()\n  } catch (err) {\n    alert(err)\n  }    \n}\n...<\/pre>\n\n\n\n<p>Here, we created a reference to the document we want to edit in Firestore using the&nbsp;<code>doc<\/code>&nbsp;function. Then, we passed that reference to the&nbsp;<code>updateDoc<\/code>&nbsp;function along with updates we want to make to the document\u2019s fields, which we got from the state.<\/p>\n\n\n\n<p>Now, we need to call the&nbsp;<code>handleUpdate<\/code>&nbsp;function when the&nbsp;<code>updateTask<\/code>&nbsp;form is submitted. To do this, modify the opening tag of the&nbsp;<code>updateTask<\/code>&nbsp;form to look like this:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ JavaScript\n\/\/ src\/EditTask.js\n&lt;form onSubmit={handleUpdate} className='editTask' name='updateTask'&gt;<\/pre>\n\n\n\n<p>With this, we are now able to edit a task in our app. To test this, in the task manager app, click on the&nbsp;<strong>Edit<\/strong>&nbsp;button and make some changes to the description and title of the task.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2021\/12\/edit-task.png\" alt=\"Edit Task\" class=\"wp-image-84034\"\/><\/figure><\/div>\n\n\n\n<p>Then, click&nbsp;<strong>Edit<\/strong>. There will be an immediate update to the task in our app since we are getting the data in real time.<\/p>\n\n\n\n<p>To view the changes we made to the task, click the&nbsp;<strong>View<\/strong>&nbsp;button.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2021\/12\/view-button.png\" alt=\"View Button\" class=\"wp-image-84036\"\/><\/figure><\/div>\n\n\n\n<p>Now, let\u2019s add the functionality to update the document in Firestore when the checkbox is clicked.<\/p>\n\n\n\n<p>Remember that when we added a task to Firestore, we also included a&nbsp;<code>completed<\/code>, which we set to&nbsp;<code>false<\/code>&nbsp;by default, signifying that a task has not been completed. When the checkbox is checked, we want the&nbsp;<code>completed<\/code>&nbsp;field value to be&nbsp;<code>true<\/code>&nbsp;and vice versa.<\/p>\n\n\n\n<p>In the&nbsp;<code>src<\/code>&nbsp;directory, go over to the&nbsp;<code>Task.js<\/code>&nbsp;file and add the following imports:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ JavaScript\n\/\/ src\/Task.js\nimport { doc, updateDoc } from \"firebase\/firestore\";\nimport {db} from '.\/firebase'\n<\/pre>\n\n\n\n<p>Now, add the following line of code after the&nbsp;<code>\/* function to update document in firestore *\/<\/code>&nbsp;comment:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ JavaScript\n\/\/ src\/Task.js\n...\n\/* function to update document in firestore *\/\nconst handleCheckedChange = async () =&gt; {\n  const taskDocRef = doc(db, 'tasks', id)\n  try{\n    await updateDoc(taskDocRef, {\n      completed: checked\n    })\n  } catch (err) {\n    alert(err)\n  }\n}\n...<\/pre>\n\n\n\n<p>For this to work, we must add an&nbsp;<code>onChange<\/code>&nbsp;event to the checkbox input to call the&nbsp;<code>handleCheckedChange<\/code>&nbsp;function.<\/p>\n\n\n\n<p>Modify the&nbsp;<strong>checkbox<\/strong>&nbsp;input, which is two lines away from the return statement. It should now look like this:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ JavaScript\n\/\/ src\/Task.js\n&lt;input \n  id={`checkbox-${id}`} \n  className='checkbox-custom'\n  name=\"checkbox\" \n  checked={checked}\n  onChange={handleCheckedChange}\n  type=\"checkbox\" \/&gt;<\/pre>\n\n\n\n<p>If we go over to our app, check the checkbox, and refresh the page, we\u2019ll notice that the checkbox is still checked.<\/p>\n\n\n\n<h3>Delete a task in Firstore<\/h3>\n\n\n\n<p>For the delete operation, we will use the&nbsp;<code>deleteDoc<\/code>&nbsp;function, which is quite simple to use. All we have to do is pass a reference to the document we want to delete to this function, and voila! It\u2019s gone.<\/p>\n\n\n\n<p>To create the functionality for deleting a task, as usual, the first step is to make the necessary imports. In the&nbsp;<code>src<\/code>&nbsp;directory, go over the&nbsp;<code>Task.js<\/code>&nbsp;file and modify the&nbsp;<code>import&nbsp;{&nbsp;doc,&nbsp;updateDoc&nbsp;}&nbsp;from&nbsp;\"firebase\/firestore\";<\/code>&nbsp;to look like this:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ JavaScript\n\/\/ src\/Task.js\nimport { doc, updateDoc, deleteDoc} from \"firebase\/firestore\";<\/pre>\n\n\n\n<p>Now, add the following line of code after the&nbsp;<code>\/* function to delete a document from firstore *\/<\/code>&nbsp;comment:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ JavaScript\n\/\/ src\/Task.js\n\/* function to delete a document from firstore *\/ \n  const handleDelete = async () =&gt; {\n    const taskDocRef = doc(db, 'tasks', id)\n    try{\n      await deleteDoc(taskDocRef)\n    } catch (err) {\n      alert(err)\n    }\n  }<\/pre>\n\n\n\n<p>Finally, let\u2019s add an&nbsp;<code><a href=\"https:\/\/blog.logrocket.com\/a-guide-to-react-onclick-event-handlers-d411943b14dd\/\" target=\"_blank\" rel=\"noreferrer noopener\">onClick<\/a><\/code>&nbsp;event to the delete button to call the&nbsp;<code>handleDelete<\/code>&nbsp;function.<\/p>\n\n\n\n<p>Scan through the return statement of the&nbsp;<code>Task<\/code>&nbsp;component. We\u2019ll see the delete button, which has a&nbsp;<code>className<\/code>&nbsp;of&nbsp;<code>task__deleteButton<\/code>. Modify the button to look like this:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ JavaScript\n\/\/ src\/Task.js\n&lt;button className='task__deleteButton' onClick={handleDelete}&gt;Delete&lt;\/button&gt;\n<\/pre>\n\n\n\n<p>Now, if we click the delete button of a task in our app, that task will be deleted from Firestore.<\/p>\n\n\n\n<p>With this, we are done building the CRUD app and everything should be working perfectly.<\/p>\n\n\n\n<h2>Conclusion<\/h2>\n\n\n\n<p>In this tutorial, we walked through how to perform CRUD operations in Firebase v9. Hopefully, at this point, you know how to carry out basic operations on Firestore when using the new Firebase library.<\/p>\n\n\n\n<p>If you still have any questions, feel free to drop it in the comments section below.<\/p>\n\n\n\n<h2>Full visibility into production React apps<\/h2>\n\n\n\n<p>Debugging React applications can be difficult, especially when users experience issues that are hard to reproduce. If you\u2019re interested in monitoring and tracking Redux state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time,&nbsp;<a href=\"https:\/\/www2.logrocket.com\/react-performance-monitoring\" target=\"_blank\" rel=\"noreferrer noopener\">try LogRocket<\/a>.&nbsp;<a href=\"https:\/\/www2.logrocket.com\/react-performance-monitoring\" target=\"_blank\" rel=\"noreferrer noopener\"><\/a><a href=\"https:\/\/www2.logrocket.com\/react-performance-monitoring\" target=\"_blank\" rel=\"noreferrer noopener\"><\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/www2.logrocket.com\/react-performance-monitoring\" target=\"_blank\" rel=\"noreferrer noopener\">LogRocket<\/a>&nbsp;is like a DVR for web and mobile apps, recording literally everything that happens on your React app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app&#8217;s performance, reporting with metrics like client CPU load, client memory usage, and more.<\/p>\n\n\n\n<p>The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.<\/p>\n\n\n\n<p>Modernize how you debug your React apps \u2014&nbsp;<a href=\"https:\/\/www2.logrocket.com\/react-performance-monitoring\" target=\"_blank\" rel=\"noreferrer noopener\">start monitoring for free<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The&nbsp;Firebase v.9 SDK&nbsp;introduces a new API surface that follows a modular approach, resulting in a change to the use of its services, one of which is&nbsp;Firestore database. Now we are left with the challenge of relearning how to perform operations like CRUD in the database.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[30],"tags":[184,65],"_links":{"self":[{"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=\/wp\/v2\/posts\/2269"}],"collection":[{"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2269"}],"version-history":[{"count":1,"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=\/wp\/v2\/posts\/2269\/revisions"}],"predecessor-version":[{"id":2270,"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=\/wp\/v2\/posts\/2269\/revisions\/2270"}],"wp:attachment":[{"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2269"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2269"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2269"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}