skip to Main Content

I am trying to make the changes in real time using nextjs and firebase firestore. However I do need to reload yet in order for me to see the changes.

const [getUsers, setUsers] = useState("");

const checkStatus = async (collectionName, valueFieldName, setterName) => {
    const q = query(
      collection(db, collectionName),
      where("isVerified", "==", valueFieldName)
    );
    const snapshot = await getCountFromServer(q);
    setterName(snapshot.data().count);
  };

and I am calling the function in the body using parameters

checkStatus("users", "false", setUsers);

and I am trying to display it by

<h1> user counter in realtime: {getUsers} </h1>

2

Answers


  1. I do need to reload yet in order for me to see the changes.

    You need to listen to updates from Firebase Firestore to update the state in real-time without needing to reload the page. For that you should use onSnapshot which listens in real time which allows you to update your application’s state and UI in real-time without needing to refresh the page.

    Here’s one example:

    import { collection, onSnapshot, query, where } from "firebase/firestore";
    import { db } from "@/firebase/firebaseConfig";
    import React, { useEffect, useState } from "react";
    
    export default function snapshot() {
        const [userCount, setUserCount] = useState(0);
    
        const checkStatus = (
          collectionName: string,
          valueFieldName: boolean,
          setterName: React.Dispatch<React.SetStateAction<number>>
        ) => {
          const q = query(
            collection(db, collectionName),
            where("isVerified", "==", valueFieldName)
          );
          const unsubscribe = onSnapshot(q, (snapshot) => {
            const count = snapshot.size;
            setterName(count);
          });
          return unsubscribe;
        };
      
        useEffect(() => {
          const unsubscribe = checkStatus("users", false, setUserCount);
          return () => {
            unsubscribe();
          };
        }, []);
      
        return (
          <div>
            <h1>User Count: {userCount}</h1>
          </div>
        );
    }
    

    If you don’t need real-time updates of the count, you can use the getCountFromServer() method instead of the onSnapshot() method to retrieve the count once the component mounts. Example for that:

    import { collection, getCountFromServer, query, where } from "firebase/firestore";
    import { db } from "@/firebase/firebaseConfig";
    import React, { useEffect, useState } from "react";
    
    export default function Home() {
      const [userCount, setUserCount] = useState(0);
    
      const checkStatus = async (
        collectionName: string,
        valueFieldName: boolean,
        setterName: React.Dispatch<React.SetStateAction<number>>
      ) => {
        const q = query(
          collection(db, collectionName),
          where("isVerified", "==", valueFieldName)
        );
        const snapshot = await getCountFromServer(q);
        const count = snapshot.data().count;
        setterName(count);
      };
    
      useEffect(() => {
        checkStatus("users", false, setUserCount);
      }, []);
    
      return (
        <div>
          <h1>User Count: {userCount}</h1>
        </div>
      );
    }
    

    Reference taken from: Count documents in Firestore Collection,
    onSnapshot

    Login or Signup to reply.
  2. Firestore’s COUNT() queries currently don’t support realtime updates. From the documentation on its limitations:

    • count() aggregation queries are currently only supported via direct server response. Queries are served only by the Cloud Firestore backend, skipping the local cache and any buffered updates. This behavior is identical to operations performed inside Cloud Firestore transactions. You cannot currently use count() queries with real-time listeners and offline queries.

    So you will indeed either have to reload the page, or set up some client-side refresh mechanism to get the latest value from the server.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search