admin管理员组

文章数量:1387356

I am trying to create a list of all documents contained in my main root collection.

I have data like this:

collection -> doc -> collection -> doc

Apologies if posts - posts is confusing!

And this is the data at root level: I was thinking something like this would work:

const [posts, setPosts] = useState();

  useEffect(() => {
    const db = firebase.firestore();
    return db.collection('posts').onSnapshot((snapshot) => {
      const postData = [];
      snapshot.forEach((doc) => postData.push({ ...doc.data(), id: doc.id }));
      setPosts(postData);
    });
  }, []);

  console.log(posts);

but this just logs an empty array when it should be an array of 2 objects.

Can anyone shine some light on where i'm going wrong? And if i will be able to access the nested data from doing this?

I am trying to create a list of all documents contained in my main root collection.

I have data like this:

collection -> doc -> collection -> doc

Apologies if posts - posts is confusing!

And this is the data at root level: I was thinking something like this would work:

const [posts, setPosts] = useState();

  useEffect(() => {
    const db = firebase.firestore();
    return db.collection('posts').onSnapshot((snapshot) => {
      const postData = [];
      snapshot.forEach((doc) => postData.push({ ...doc.data(), id: doc.id }));
      setPosts(postData);
    });
  }, []);

  console.log(posts);

but this just logs an empty array when it should be an array of 2 objects.

Can anyone shine some light on where i'm going wrong? And if i will be able to access the nested data from doing this?

Share Improve this question edited May 5, 2020 at 14:30 Thomas Allen asked May 5, 2020 at 14:19 Thomas AllenThomas Allen 8118 gold badges18 silver badges33 bronze badges 2
  • can you show a screen shot of your database? Note that Firestore queries are shallow. – Renaud Tarnec Commented May 5, 2020 at 14:20
  • Sure, just added – Thomas Allen Commented May 5, 2020 at 14:23
Add a ment  | 

2 Answers 2

Reset to default 3

Update after your ment and the screenshot addition

We can see that the documents in the parent posts collection are displayed with an italic font in the Firebase console: this is because these documents are only present (in the console) as "container" of one or more sub-collection but they are not "genuine" documents.

As matter of fact, if you create a document directly under a col1 collection with the full path doc1/subCol1/subDoc1, no intermediate documents will be created (i.e. no doc1 document).

The Firebase console shows this kind of "container" (or "placeholder") in italics in order to "materialize" the hierarchy and allow you to navigate to the subDoc1 document but doc1 document doesn't exist in the Firestore database.

Let's take an example: Imagine a doc1 document under the col1 collection

col1/doc1/

and another one subDoc1 under the subCol1 (sub-)collection

col1/doc1/subCol1/subDoc1

Actually, from a technical perspective, they are not at all relating to each other. They just share a part of their path but nothing else. One side effect of this is that if you delete a document, its sub-collection(s) still exist.

So, it is normal that you get an empty array when doing db.collection('posts').onSnapshot((snapshot) => {...}), because you are listening to un-existing documents.


What you could do is to listen for the documents in one of the posts subcollection, as follows:

db.collection('posts').doc('frlGy...').collection('posts').onSnapshot((snapshot) => {...});

Another possibility would be to use a Collection Group query, to get all the elements in ALL the posts subcollections. But in this case you cannot have the parent and subcollections sharing the same name (i.e. posts).


Update following your second ment

Will I need to do it differently if I, for example, want to be able to log all posts from all Users, as the Users documents technically wont exist?

It all depends if you have some user documents or not, which is not clear.

If you do, for each of those user documents, create a posts subcollection, and use db.collection('Users').doc(user.uid).collection('posts').onSnapshot((snapshot) => {...});

You can also use a Collection Group query to query across the different posts subcollections.

If you don't have user documents, you can have a global posts collection (root collection) and you save the user uid as a field of each post document. This way you can secure them (with Security rules) and also query all posts by user. You can also easily query posts across all users.


You need to put the console.log within the callback, as follows:

const [posts, setPosts] = useState();

  useEffect(() => {
    const db = firebase.firestore();
    return db.collection('posts').onSnapshot((snapshot) => {
      const postData = [];
      snapshot.forEach((doc) => postData.push({ ...doc.data(), id: doc.id }));
      console.log(postData);  // <------
      setPosts(postData);
    });
  }, []);

Also note that this will only return the frlGy... document, not the one in the subcollection: as said above, Firestore queries are shallow. If you want to query the subcollection, you need to execute an additional query.

   const getMarkers= async ()=> { 
        await db.collection('movies').get()
          .then(querySnapshot => {
            querySnapshot.docs.forEach(doc => {
            setlist(doc.data().title);
          });
        });
      }

Its so simple just add async and await on a function and call the function in useeffect

本文标签: javascriptGet all documents in Firebase collectionReactStack Overflow