skip to Main Content

I have collections of restaurants.
ss1

I want to retrieve single document.However, I don’t have documentID, I only have email so I want to write a query which returns a single document when i give it an
The email field is unique there will be no duplicated document with it.

I am current using this silly query:

      const q = query(
        collection(fireStore, "restaurant"),
        where("email", "==", user?.email),
        limit(1)
      )
      const querySnapshot = await getDocs(q);
      querySnapshot.forEach((doc) => {
         setRestaurant(doc.data());
      });

The querySnapshot is an array which contains single element.

Is it possible to write a query which return single document not an array of single document?

or you can also suggest better ways to doing this like first find documentID then retrieve with documentID.

2

Answers


  1. Since a query can match multiple documents, it will always return a QuerySnapshot and that will always contains an array of documents. Even if the query only returns a single document, it will be in the form of a QuerySnapshot and an array.

    If you know there is only a single document, or if you only care about the first document of the results, you can access that without needing a loop:

    const doc = querySnapshot.docs[0];
    setRestaurant(doc.data());
    
    Login or Signup to reply.
  2. As an alternative to Frank’s answer, you could also create your own getter function that returns the first result as if you were using getDoc().

    async function getFirstDoc(queryObj) {
        const querySnapshot = await getDocs(
          query(queryObj, limit(1)) // adds the limit constraint for efficiency
        );
        return querySnapshot.docs[0]
          || {
            exists: () => false,
            get: () => undefined,
            data: () => undefined
          };
    }
    

    Then you can use it elsewhere in your code like so:

    const q = query(
      collection(fireStore, "restaurant"),
      where("email", "==", user?.email)
    );
    
    const doc = await getFirstDoc(q);
    setRestaurant(doc.data()); // assuming doc always exists, otherwise check doc.exists()
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search