Search code examples
javascriptreactjsgoogle-cloud-firestorematerial-uimui-datatable

Firebase pagination with Mui-Datatable pagination and sorting


How can I use server-side pagination and filtering of the Mui-Datatable for displaying the data? As of now, I have not made it work yet. These are the codes I have done.

I also have a problem where the all of the firestore data is being fetch instead of just 10 data. The 10 comes from the rowsPerPage.

Recreated codesandbox: https://codesandbox.io/s/mui-datatable-server-side-pagination-filtering-and-sorting-y8pyp7

export default function App() {
  const [users, setUsers] = useState([]);
  const [loading, setLoading] = useState(false);
  const [count, setCount] = useState(1);
  const [rowsPerPage, setRowsPerPage] = useState(10);

  useEffect(() => {
    let isMounted = true;

    const getUsers = async () => {
      const querySnapshot = await getDocs(
        collection(db, "users"),
        orderBy("firstName", "asc"),
        limit(rowsPerPage)
      );
      const arr = [];
      querySnapshot.forEach((doc) => {
        arr.push({
          ...doc.data()
        });
      });
      if (isMounted) {
        setUsers(arr);
        setCount(arr.length);
        loading(true);
      }
    };

    getUsers().catch((err) => {
      if (!isMounted) return;
      console.error("failed to fetch data", err);
    });

    return () => {
      isMounted = false;
    };
  }, []);

  const columns = [
    {
      name: "firstName",
      label: "First Name",
      options: {
        filter: false,
        display: true
      }
    },
    {
      name: "lastName",
      label: "Last Name",
      options: {
        filter: false,
        display: true
      }
    },

    {
      name: "number",
      label: "Number",
      options: {
        filter: false,
        sort: true
      }
    }
  ];

  console.log(rowsPerPage, "rowsPaerPage");
  console.log(users, "users");

  const options = {
    print: true,
    filterType: "multiselect",
    selectableRows: "none",
    responsive: "standard",
    fixedHeader: true,
    count: count,
    rowsPerPage: rowsPerPage,
    serverSide: true
  };

  return (
    <div className="App">
      <ThemeProvider theme={createTheme()}>
        <MUIDataTable
          title={"Reports"}
          options={options}
          columns={columns}
          data={users}
        />
      </ThemeProvider>
    </div>
  );
}

Solution

  • You should use the query() method when you want to use the limit() and orderBy() method. See code below:

        const getUsers = async () => {
          const usersRef = collection(db, "users");
          const q = query(
              usersRef,
              orderBy("firstName", "asc"),
              limit(rowsPerPage)
              );
          const querySnapshot = await getDocs(q);
          const arr = [];
          querySnapshot.forEach((doc) => {
            arr.push({
              ...doc.data()
            });
          });
          if (isMounted) {
            setUsers(arr);
            setCount(arr.length);
            loading(true);
          }
        };
    

    For more information, you may checkout these documentations: