2

I am trying to get all the documents from a Firestore collection. I am following their docs to do so. However, nothing happens. I do not see anything console-logging or any errors whatsoever. Basically, nothing happens, as if the get() function is not working. I am clueless as to what is going on.

Here's the code with the get(). It is written in ReactJS with hooks:

import React, { useState, useEffect } from 'react';
import firebase from '../firebase.js';
import './Messages.css';


function Messages (props) {


    const [messages, setMessages] = useState([]);
    const [customers, setCustomers] = useState([]);   

    useEffect(() => {         
    
            const query = firebase
            .firestore()
            .collection("Chats")
            .get()
            .then((querySnapshot) => {           
                querySnapshot.forEach((doc) => {
    
                    if (doc.exists) {
                        console.log(doc)                    
                    } else {
                        console.log('nothing')
                    }
                   console.log(doc.id, " => ", doc.data());
                });
            }).catch((error) => {
                console.log("Error getting documents: ", error);
            });
    
     }, []);

Similarly, the same thing was happening to the onSnapShot function that I tried to use as follows:

    useEffect(() => {         
        
               const unsub = query.onSnapshot(async querySnapshot => {
    
                if (querySnapshot.docChanges().length > 0) {
    
                    const data = querySnapshot.docs.map((doc) => {
    
                        return { body: doc.data(), id: doc.id }
    
                    }
    
                    );
    
                    const allData = await Promise.all(data)
    
                    setCustomers(allData);
                    
    
                } else { console.log("no data") }
    
            }, (error) => {
                console.log("Error listening to documents: ", error);
            })
   return () => {
            unsub();
        };

         }, []);

The Customers state is empty and console-logging from anywhere within Querysnapshot function does not work. Strangely, however, similar set-ups/codes work in my other components. Adding dependencies or placing the code into another function (fetchData()) and calling it within useEffect did not work. I am also certain it is not an issue with Rules as I am accessing Firestore as an admin for which I have an appropriate Rule set up (match /{documents=**} { allow write, read: if request.auth.token.admin == true; }). I am clueless as to what is going on. Please help.

P.S. The following code does work within the useEffect in the same component, however, but since I can not figure out how to get rid of duplicates that I get from the query in the customers state (tried array.includes and indexof but failed) as I kept getting only one same object, I am ditching the following code in favor of one of the above.

const query = firebase.firestore()        
        .collectionGroup('Messages')
        .orderBy("timestamp", "desc")

        const unsub = query.onSnapshot((snapshot) => {

            if (snapshot.empty) {
                console.log('No matching documents.');
                return;
            }  

            snapshot.docs.map((doc) => {                 

                console.log("1")               

                if (customers.length ) {
                    console.log("1b")
                    customers.map((customer) => {
                    console.log("2")
                    if (customer.uid.indexOf(doc.data().uid) === -1) {    
                        console.log("3")                                        
                        setCustomers(prevFiles => ([...prevFiles, {
                                        name: doc.data().name, uid: doc.data().uid
                                }]))
                    } 
                })
                } else  {
                    console.log("4")
                    setCustomers([{name: doc.data().name, uid: doc.data().uid}])                
                }               

                

            });                      
           

        }, (error) => {
            console.log('Error getting messages', error);
        })
DonBergen
  • 127
  • 1
  • 9
  • is authenticated? When u use inspect in chrome, go to networking -> WS, then you can see if anything is going on in the websocket layer. – Someone Special Mar 30 '21 at 03:51
  • what is your 'firebase.js` code is? – Nimna Perera Mar 30 '21 at 03:55
  • What do you mean "is authenticated"? I signed in, of course. What am I supposed to see happening in Inspect-Network-WS. I see some lines running front and back in different colors. I do not understand much about that part, though. Please clarify. – DonBergen Mar 30 '21 at 04:03
  • In my firebase.js, I have my firebaseConfig which I believe is all correct as my Firebase is working well in other components. It is only malfunctioning in Messages.js for some reason. – DonBergen Mar 30 '21 at 04:05
  • By the way, if I console.log(query) which is the const query = firebase.firestore().collection("Chats").get(). I can see the log and it seems correct. It is only the get() and onSnapshot() that are not responsive at all for some reason. – DonBergen Mar 30 '21 at 04:08
  • There is no return for query. So it won't work as you expected. Instead try to use `async/await` to get the data from collection. If you want to learn [how to use async/await in useEffect()](https://stackoverflow.com/a/53572588/10182897). Please learn `Promise` in js – Ashish Mar 30 '21 at 04:20
  • What do you mean no return for the query? What makes you think async/await is a solution? It is not, unfortunately. I tried the following: async function fetchMyAPI() { const clientsRef = firebase.firestore().collection('Chats'); const snapshot = await clientsRef.get(); snapshot.forEach(doc => { console.log(doc.id, '=>', doc.data()); }); } fetchMyAPI() – DonBergen Mar 30 '21 at 23:05
  • I figured it out. Snapshot was empty. Should have checked it first. See my answer below if interested. Thanks for trying to help, though. Happy coding. – DonBergen Mar 31 '21 at 00:25

1 Answers1

2

I figured it out. This might be very useful for somebody who is in a similar situation to know as this does not seem to be explained in the Firestore docs.

Anyways, the reason nothing was happening and console.logging was not working was because the query was empty. So, make sure to always check that your collection has documents which in turn have some information. The documents that I was trying to get contained a collection and named after user ids which I needed. However, since they did not really contain any information, they could not be retrieved. And, I did not know that. I simply needed the names of the documents, the uids.

One way you can check if your snapshot is empty is as follows:

if (snapshot.empty) {
                console.log('No matching documents.');
                return;
            }

In my code, it looks like this:

const query = firebase
        .firestore()
        .collection("Chats")
        .get()
        .then((querySnapshot) => {

                if (querySnapshot.empty) {
                console.log('No matching documents.');
                return;
            }

            querySnapshot.forEach((doc) => {

                if (doc.exists) {
                    console.log(doc)
                    setCustomers(prevFiles => ([...prevFiles, {
                    id: doc.data().id, data: doc.data()
                            }]))
                } else {
                    console.log('nothing')
                }
                // doc.data() is never undefined for query doc snapshots
                console.log(doc.id, " => ", doc.data());
            });
        }).catch((error) => {
            console.log("Error getting documents: ", error);
        });

Basically, it will never get to the forEach part if it is empty.

Hope this sheds some light on some confusion that someone might have about the docs in collections. They must contain info to be retrievable. Happy coding.

DonBergen
  • 127
  • 1
  • 9