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
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:
if I just refresh it comes back:
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
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
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.