Know how to link your React JS MUI Data Table project with Firebase.
Provided additional features like deleting and searching records.
// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";
// 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
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
apiKey: "AIzaSyCbeVQw2MlQOSE-97UyMx7IJKiSgvVqYYY",
authDomain: "crud-b15f0.firebaseapp.com",
projectId: "crud-b15f0",
storageBucket: "crud-b15f0.appspot.com",
messagingSenderId: "286952407725",
appId: "1:286952407725:web:b225d47ef9b394479b3c24",
measurementId: "G-1MDC27LYW2"
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
export const db = getFirestore(app);
import { useEffect, useState } from "react";
import Paper from "@mui/material/Paper";
import Table from "@mui/material/Table";
import TableBody from "@mui/material/TableBody";
import TableCell from "@mui/material/TableCell";
import TableContainer from "@mui/material/TableContainer";
import TableHead from "@mui/material/TableHead";
import TablePagination from "@mui/material/TablePagination";
import TableRow from "@mui/material/TableRow";
import Typography from "@mui/material/Typography";
import Divider from "@mui/material/Divider";
import AddCircleIcon from "@mui/icons-material/AddCircle";
import Button from "@mui/material/Button";
import Box from "@mui/material/Box";
import Stack from "@mui/material/Stack";
import { db } from "../firebase-config";
import {
collection,
getDocs,
addDoc,
updateDoc,
deleteDoc,
doc,
} from "firebase/firestore";
import EditIcon from "@mui/icons-material/Edit";
import DeleteIcon from "@mui/icons-material/Delete";
import Swal from "sweetalert2";
import TextField from "@mui/material/TextField";
import Autocomplete from "@mui/material/Autocomplete";
export default function UsersList() {
const [page, setPage] = useState(0);
const [rowsPerPage, setRowsPerPage] = useState(5);
const [rows, setRows] = useState([]);
const empCollectionRef = collection(db, "products");
useEffect(() => {
getUsers();
}, []);
const getUsers = async () => {
const data = await getDocs(empCollectionRef);
setRows(data.docs.map((doc) => ({ ...doc.data(), id: doc.id })));
};
const handleChangePage = (event, newPage) => {
setPage(newPage);
};
const handleChangeRowsPerPage = (event) => {
setRowsPerPage(+event.target.value);
setPage(0);
};
const deleteUser = (id) => {
Swal.fire({
title: "Are you sure?",
text: "You won't be able to revert this!",
icon: "warning",
showCancelButton: true,
confirmButtonColor: "#3085d6",
cancelButtonColor: "#d33",
confirmButtonText: "Yes, delete it!",
}).then((result) => {
if (result.value) {
deleteApi(id);
}
});
};
const deleteApi = async (id) => {
const userDoc = doc(db, "products", id);
await deleteDoc(userDoc);
Swal.fire("Deleted!", "Your file has been deleted.", "success");
getUsers();
};
const filterData = (v) => {
if (v) {
setRows([v]);
} else {
getUsers();
}
};
return (
<>
{rows.length > 0 && (
<Paper sx={{ width: "98%", overflow: "hidden", padding: "12px" }}>
<Typography
gutterBottom
variant="h5"
component="div"
sx={{ padding: "20px" }}
>
Products List
</Typography>
<Divider />
<Box height={10} />
<Stack direction="row" spacing={2} className="my-2 mb-2">
<Autocomplete
disablePortal
id="combo-box-demo"
options={rows}
sx={{ width: 300 }}
onChange={(e, v) => filterData(v)}
getOptionLabel={(rows) => rows.name || ""}
renderInput={(params) => (
<TextField {...params} size="small" label="Search Products" />
)}
/>
<Typography
variant="h6"
component="div"
sx={{ flexGrow: 1 }}
></Typography>
<Button variant="contained" endIcon={<AddCircleIcon />}>
Add
</Button>
</Stack>
<Box height={10} />
<TableContainer>
<Table stickyHeader aria-label="sticky table">
<TableHead>
<TableRow>
<TableCell align="left" style={{ minWidth: "100px" }}>
Name
</TableCell>
<TableCell align="left" style={{ minWidth: "100px" }}>
Price
</TableCell>
<TableCell align="left" style={{ minWidth: "100px" }}>
Category
</TableCell>
<TableCell align="left" style={{ minWidth: "100px" }}>
Date
</TableCell>
<TableCell align="left" style={{ minWidth: "100px" }}>
Action
</TableCell>
</TableRow>
</TableHead>
<TableBody>
{rows
.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
.map((row) => {
return (
<TableRow
hover
role="checkbox"
tabIndex={-1}
key={row.code}
>
<TableCell align="left">{row.name}</TableCell>
<TableCell align="left">{row.price}</TableCell>
<TableCell align="left">{row.category}</TableCell>
<TableCell align="left">{row.date}</TableCell>
<TableCell align="left">
<Stack spacing={2} direction="row">
<EditIcon
style={{
fontSize: "20px",
color: "blue",
cursor: "pointer",
}}
className="cursor-pointer"
// onClick={() => editUser(row.id)}
/>
<DeleteIcon
style={{
fontSize: "20px",
color: "darkred",
cursor: "pointer",
}}
onClick={() => {
deleteUser(row.id);
}}
/>
</Stack>
</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
</TableContainer>
<TablePagination
rowsPerPageOptions={[5, 10, 25]}
component="div"
count={rows.length}
rowsPerPage={rowsPerPage}
page={page}
onPageChange={handleChangePage}
onRowsPerPageChange={handleChangeRowsPerPage}
/>
</Paper>
)}
</>
);
}