简体   繁体   中英

ReactJS, Firebase - Firestore, issue with the dynamic read of subcollections

I am a junior dev and at this moment am working on a forum done with ReactJS and Firebase.

I am having an issue with the dynamic read of subcollections.

Here is a screen shot of my Firestore.

在此处输入图像描述

Topics have each a Topic document and a posts collection(well subcollection).

I have tried many ways to retrieve the data from subcollections dynamically, but none works. Been diving in stackoverflow, in articles but I am stuck. The queries for the Topics work well, and the posts too but not dynamically. If you could help I will be very grateful because searching for a solution has lasted for a while, so Thank you in advance.

These are my imports:

import firebase from 'firebase';
import * as admin from 'firebase-admin';
import * as functions from 'firebase-functions';

and in separate file there is the firebaseConfig and also firebase is initialized.

These are the queries:

const db = firebase.firestore();
const dbPostsCollection = db.collection("topics");

const [data, setData] = useState([]);

My first and main query, which brings me closest to what I want as a result but can't retrieve the data.

 useEffect(() => {
    dbPostsCollection.get().then(function(querySnapshot) {
        querySnapshot.forEach(function(doc) {
            console.log(doc.id, " => ", doc.data());
            console.log(doc.id, " => ", db.collection("posts"));
        });
    });    
}, []);

There is no error, below you'll see an screenshot of the console.logs

在此处输入图像描述

Second query:

useEffect(() => { 
    dbPostsCollection
    .get()
    .then(function (Document) {
       Document.forEach((subCollectionSnapshot) => {
            const postsData = subCollectionSnapshot.map(subcollection =>               
                subcollection.data())
                console.log(postsData); // array of posts objects
                setData(postsData);
            });
        }
        );
}, []);

the error message: Unhandled Rejection (TypeError): subCollectionSnapshot.map is not a function

And the last query (there are more than 3 but I'll spare you from reading all my trials):

useEffect(() => {
    dbPostsCollection
    .get()
    .then((querySnapshot) => {  
        querySnapshot.forEach((doc) => {
            console.log(doc.id, " => ", doc.data());
            console.log(doc.id, " => ", db.collection("posts").get().then(querySnapshot => {
                const data = querySnapshot.docs.map(doc => doc.data());
                console.log(data);
            }));
        })
    }); 
}, []);

This query doesn't return the Promise result, the result is undefined. Thank you again for your help!

useEffect() is by definition and requirement a SYNCHRONOUS function, and Firestore operations are ASYNCHRONOUS - likely your useEffect() is exiting before any Firestore activity occurs.

A common hack is to create a self-executing closure inside the useEffect() to effectively "spawn" a thread:

useEffect(() => {
  (async () => {
    await dbPostsCollection
    .get()
    .then((querySnapshot) => {  
        querySnapshot.forEach((doc) => {
            console.log(doc.id, " => ", doc.data());
            console.log(doc.id, " => ", db.collection("posts").get().then(querySnapshot => {
                const data = querySnapshot.docs.map(doc => doc.data());
                console.log(data);
            }));
        })
    });
  })(); 
}, []);

The (async () => {}) returns the anonymous ARROW FUNCTION; the await indicates to wait for the following commend to execute (effectively waiting for the implied Promise to resolve); the following () executes it. The arrow function returns a Promise , which the useEffect pretty much ignores, but the function does run to completion.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM