2

I have a DataGrid table with data that comes from Firebase and I wanted to know how can I delete and update the firebase information ?

I have this piece of code that deletes the row and it does works BUT because I haven't add anything to update the firebase it will not delete it permanently (which makes perfect sense):

Edit: Deleted unnecessary piece of code to just leave delete function this is just after a row has been check then it let's you delete that checked row (and it works) but I don't see space (it brings out compile errors) to add the firebase delete() function in that piece of code.

          <IconButton
            onClick={() => {
              const selectedIDs = new Set(selectionModel);
              setEstudiantes((r) => 
              r.filter((x) => 
              !selectedIDs.has(x.id)
              ));
            }}
          >
            <DeleteOutlinedIcon />
          </IconButton>

This is how I do the check of the rows (and it does work):

checkboxSelection
        //Store Data from the row in another variable
        onSelectionModelChange = {(id) => {
          setSelectionModel(id);
          const selectedIDs = new Set(id);
          const selectedRowData = estudiantes.filter((row) =>
            selectedIDs.has(row.id)
          );
          setEstudiantesData(selectedRowData)
        }
      }
        {...estudiantes}

However I do have the delete function that connects with my firebase and deletes documents that I did before migrating to MUI DataGrid but I do not know how to integrated it. This is how you delete something in firebase usually

db.collection("usuarios")
.doc(user.uid)
.collection("estudiantes")
.doc(document name variable)
.delete();

Thank you any tip/help is welcome.

*UPDATE this is how it looks

enter image description here

it does the delete as intended but it doesn't update the firebase and idk where to add the code that does that because w/e I try to add it it comes out as an error:

enter image description here

if I just refresh it comes back:

enter image description here

UPDATE Adding the code of the DataGrid:

return (
      <Container fixed>
      <Box mb={5} pt={2} sx={{textAlign:'center'}}>
      <Button
      startIcon = {<PersonAddIcon />} 
      variant = "contained" 
      color = "primary" 
      size = "medium" 
      onClick={crearEstudiante} >
      Crear Estudiantes
      </Button>
      <Box pl={25} pt={2} mb={2} sx={{height: '390px', width: "850px", textAlign:'center'}}>
      <DataGrid
        rows={estudiantes}
        columns={columns}
        pageSize={5}
        rowsPerPageOptions={[5]}

        components={{
          Toolbar: CustomToolbar,
        }}

        checkboxSelection
        //Store Data from the row in another variable
        onSelectionModelChange = {(id) => {
          setSelectionModel(id);
          const selectedIDs = new Set(id);
          const selectedRowData = estudiantes.filter((row) =>
            selectedIDs.has(row.id)
          );
          setEstudiantesData(selectedRowData)
        }
      }
        {...estudiantes}
        
      />
      </Box>
      <Button
      startIcon = {<ShoppingCartSharpIcon />} 
      variant = "contained" 
      color = "primary" 
      size = "medium" 
      onClick={realizarPedidos} >
      Crear pedido
      </Button>
      </Box></Container>
    )

Update Adding picture of the error I get when I try to add the logic to update the firebase, doesn't matter where I put it inside the delete logic it just gives me an error, I honestly do not know where to put it since I don't understand very well the selection of MUI on DataGrid

enter image description here

Update Adding my whole code:

import React, { useState, useEffect} from 'react'
import {db} from './firebase';
import { useHistory } from 'react-router-dom';
import "./ListadoEstudiantes.css"
import { DataGrid, 
  GridToolbarContainer, GridToolbarFilterButton, GridToolbarDensitySelector} from '@mui/x-data-grid';
import { Button, Container } from "@material-ui/core";
import { IconButton} from '@mui/material';
import PersonAddIcon from '@mui/icons-material/PersonAddSharp';
import ShoppingCartSharpIcon from '@mui/icons-material/ShoppingCartSharp';
import DeleteOutlinedIcon from '@mui/icons-material/DeleteOutlined';
import { Box } from '@mui/system';

function ListadoEstudiantes({user}) {

  const history = useHistory("");
  const crearEstudiante = () => {
    history.push("/Crear_Estudiante");
  };

 const [estudiantesData, setEstudiantesData] = useState([])

 const parseData = {
  pathname: '/Crear_Pedidos',
  data: estudiantesData
}

const realizarPedidos = () => {
  if(estudiantesData == 0)
  {
    window.alert("Seleccione al menos un estudiante")
  }
  else {
    history.push(parseData);
  }
};

 function CustomToolbar() {
  return (
    <GridToolbarContainer>
      <GridToolbarFilterButton />
      <GridToolbarDensitySelector />
    </GridToolbarContainer>
  );
}


const [estudiantes, setEstudiantes] = useState([]);
const [selectionModel, setSelectionModel] = useState([]);
  const columns = [
  { field: 'id', headerName: 'ID', width: 100 },

  {field: 'nombre', headerName: 'Nombre', width: 200},

  {field: 'colegio', headerName: 'Colegio', width: 250},

  {field: 'grado', headerName: 'Grado', width: 150},
    {
      field: "delete",
      width: 75,
      sortable: false,
      disableColumnMenu: true,
      renderHeader: () => {
        return (
          <IconButton
            onClick={() => {
              const selectedIDs = new Set(selectionModel);
              setEstudiantes((r) => 
              r.filter((x) => 
              !selectedIDs.has(x.id)
              ));
            }}
          >
            <DeleteOutlinedIcon />
          </IconButton>
        );
      }
    }
  ];

  const deleteProduct = (estudiante) => {
    if (window.confirm('Quiere borrar este estudiante ?')){
        db.collection("usuarios").doc(user.uid).collection("estudiantes").doc(estudiante).delete();
    }
}

useEffect(() => {
}, [estudiantesData])

 const estudiantesRef = db.collection("usuarios").doc(user.uid).collection("estudiantes")
 useEffect(() => {
  estudiantesRef.onSnapshot(snapshot => {
    const tempData = [];
    snapshot.forEach((doc) => {
      const data = doc.data();
      tempData.push(data);
    });
    setEstudiantes(tempData);
    
    console.log(estudiantes)
  })
 }, []);

 useEffect (() => {
  const estData = window.localStorage.getItem("estudiantes");
  setEstudiantes(JSON.parse(estData))
}, [])

 useEffect (() => {
   window.localStorage.setItem("estudiantes", JSON.stringify(estudiantes))
 })

    return (
      <Container fixed>
      <Box mb={5} pt={2} sx={{textAlign:'center'}}>
      <Button
      startIcon = {<PersonAddIcon />} 
      variant = "contained" 
      color = "primary" 
      size = "medium" 
      onClick={crearEstudiante} >
      Crear Estudiantes
      </Button>
      <Box pl={25} pt={2} mb={2} sx={{height: '390px', width: "850px", textAlign:'center'}}>
      <DataGrid
        rows={estudiantes}
        columns={columns}
        pageSize={5}
        rowsPerPageOptions={[5]}

        components={{
          Toolbar: CustomToolbar,
        }}

        checkboxSelection
        //Store Data from the row in another variable
        onSelectionModelChange = {(id) => {
          setSelectionModel(id);
          const selectedIDs = new Set(id);
          const selectedRowData = estudiantes.filter((row) =>
            selectedIDs.has(row.id)
          );
          setEstudiantesData(selectedRowData)
        }
      }
        {...estudiantes}
        
      />
      </Box>
      <Button
      startIcon = {<ShoppingCartSharpIcon />} 
      variant = "contained" 
      color = "primary" 
      size = "medium" 
      onClick={realizarPedidos} >
      Crear pedido
      </Button>
      </Box></Container>
    )
}

export default ListadoEstudiantes
ReactPotato
  • 1,262
  • 3
  • 26
  • 46
  • From this [stackoverflow thread](https://stackoverflow.com/questions/64232909/how-to-delete-a-specific-row-in-material-ui-datagrid-reactjs/64233451), I found a [link](https://codesandbox.io/s/heuristic-davinci-n3vrz?file=/src/App.js) of a codesandbox that has the source code on how to delete the specific row from Material UI Datagrid Table, and for the row/data to get deleted from firebase firestore too, add the deleteProduct function on onClick of Icon button like this onClick ={deleteProduct} and check if this works. – Priyashree Bhadra Oct 01 '21 at 10:11
  • From what I saw is almost the same method of delete that I'm using for my rows however is not from firebase I don't see any update method for the firebase in that code. – ReactPotato Oct 01 '21 at 14:47
  • Yeah I just shared it for reference. I think I understood what you need. You are deleting a row from the table but it is not updating in the firebase. Can you have a look at this [stackoverflow thread](https://stackoverflow.com/a/69386032/15803365)? – Priyashree Bhadra Oct 01 '21 at 15:26
  • I do have the button that deletes + The code that updates from firebase I just don't know how to integrated it because w/e I add the update code it comes out with an error. – ReactPotato Oct 01 '21 at 15:31
  • What is the error you are getting? – Priyashree Bhadra Oct 01 '21 at 15:34
  • Just compile errors as if I'm not allowed to add that kind of code there. – ReactPotato Oct 01 '21 at 15:37
  • I think this [tutorial](https://medium.com/@sarahzhan/building-a-todo-app-with-crud-operations-using-firebase-react-hooks-and-material-ui-caf4b1f2ecbc) will help you. – Priyashree Bhadra Oct 01 '21 at 15:58
  • Thank you, however as I mentioned before I do know how to do those things. it just doesn't let me add my code to the delete function added by the MUI Button because it brings out a compile error. I have both codes I want to merge/integrate them and make them work on that delete button. – ReactPotato Oct 01 '21 at 16:33
  • Try 1 : Can you do : onClick ={ deleteProduct} and const deleteProduct = () => { if (window.confirm('Quiere borrar este estudiante ?')){ db.collection("usuarios").doc(user.uid).collection("estudiantes").doc(estudiante).delete(); } } Try 2 : onClick{(e)=> db.collection("usuarios").doc(user.uid).collection("estudiantes").doc(estudiante).delete();} – Priyashree Bhadra Oct 01 '21 at 16:57
  • No because in the function I added at the start is based on delete after checking something is being checked. I can't just delete the check function and add the db.collection.......delete(); because it won't know what to delete. – ReactPotato Oct 01 '21 at 17:03
  • Please add your code for the DataGrid. I'd like to see it maybe I'll be able to help. Also please add the error you're getting in an image and attach it to the question. You don't have to add all of it, just a few lines should do. If you don't want to add an image to the question, upload it somewhere and share the link. – Nizar Oct 06 '21 at 21:19
  • I'll add the relevants pieces of the code @Nizar. If you require whole code let me know – ReactPotato Oct 06 '21 at 22:58
  • Check out my answer please, let me know if it works out for you – Nizar Oct 07 '21 at 05:27

1 Answers1

1

So after you filter estudiantes, you're left with the items that the user does not want to delete. But before we do that, we're going to have to get the items that the user wants to delete so we can delete them from Firebase.

You could replace the onClick function of the delete button with:

onClick={() => {
const selectedIDs = new Set(selectionModel);
estudiantes.filter((x) =>
selectedIDs.has(x.id)).map( x => {
db.collection("usuarios").doc(user.uid).collection("estudiantes").doc(x.uid).delete()
})
)
////If NOT updating from db add this 
setEstudiantes(estudiantes.filter((x) =>
!selectedIDs.has(x.id)))
}}

Items that the user wants to delete are in selectedIDs so we need to use selectedIDs.has(x.id) instead of !selectedIDs.has(x.id). Now we're left with an array that includes only the items for deletion. We map this array to delete each one of these selected items. By using the map method.

After this, you can filter estudiantes since now we don't need the items we just deleted from Firebase. (you can skip this one if you're updating from firebase as the new data won't include deleted items).

Please let me know if this is what you were looking for.

Nizar
  • 737
  • 6
  • 15
  • I tried this and modified a bit cause you can't have `db.collection.doc(user.uid).collection("estudiantes").doc(estudiante).delete()` you can't just say `db.collection` and jump to `doc` instantly without calling the collection first. `db.collection("usuarios").doc(user.uid).collection("estudiantes").doc(document name variable).delete();` Anyways I tried this and it literally bricked my code I try deleting the whole checkbox and what I added and it just won't work anymore it just constantly show an error – ReactPotato Oct 07 '21 at 14:21
  • Can you show me the click function of the delete button? How are you handling clicks? – Nizar Oct 07 '21 at 14:30
  • I did, the onClick function deletes the row perfectly fine but since it doesn't update from firebase it just comes back is right there on top of the question. Also I try it but instead of deleating I just used a console.log to check what is printing and it says .map is not a function. – ReactPotato Oct 07 '21 at 14:32
  • r is an array right? try to just do console.log(r.filter((x)=> seletedIDs.has(x.id) )) let me know what it shows – Nizar Oct 07 '21 at 14:34
  • that's correct it represents setEstudiantes which it is an array yes. – ReactPotato Oct 07 '21 at 14:35
  • so does doing this show you the users you want to delete? console.log(r.filter((x)=> seletedIDs.has(x.id) )) – Nizar Oct 07 '21 at 14:36
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/237924/discussion-between-nizar-and-reactpotato). – Nizar Oct 07 '21 at 14:36