What is the best way to retrieve nested reference data all at once from a Firestore document?

I have two distinct collections stored within my Firestore database.

The first collection is users, and it can be visualized as shown here:

https://i.stack.imgur.com/AKlyM.png

The second collection is posts, represented by the following structure:

https://i.stack.imgur.com/fVvI8.png

In my database setup, I am storing a reference to the user document within each post entry. Whenever I retrieve a particular post, I also want to fetch detailed information about the respective users. However, the current implementation requires me to perform additional operations like the one depicted below:

const [userPosts, setUserPosts] = useState([]);

useEffect(async function () {
  if (initialized && user) {
    let snap = await firebase.firestore().collection('posts').where("author", "==", firebase.firestore().collection('users').doc(user)).get();
    let docs = snap.docs.map(doc => doc.data());

    for (let i = 0; i < docs.length; i++) {
      let doc = docs[i];
      docs[i] = { ...doc, author: (await doc.author.get()).data().email }
    }

    setUserPosts(docs);
  }
}, [user]);

This method proves to be inefficient since it necessitates fetching the user document for every post individually.

Would you recommend a more efficient approach?

Answer №1

When structuring your data in Cloud Firestore, it's important to approach it differently than a traditional database. Cloud Firestore is a NoSQL, document-oriented database that doesn't use tables or rows. Instead, data is stored as documents with key-value pairs, which can include simple fields like strings or more complex objects like lists.

The documentation provides a helpful example of using subcollections for storing messages. A subcollection is a collection linked to a specific document, allowing you to organize your data effectively.

users:
    userA:
        name: "Mickey Mouse"
        email: <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="2855613d47594048435c51544552594558511e535f5d">[email protected]</a>
        posts:
            post1:
                date: 2021-02-09
            post2:
                date: 2021-02-10
    userB:
    ....
var messageRef = db.collection('users').doc('userA')
                .collection('posts').doc('post1');

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Sharing the checkbox's checked status with an AJAX script

I am faced with a challenge involving a table that contains checkboxes in the first column. When a checkbox is checked, it triggers an AJAX script that updates a PHP session variable with the selected values. The functionality is currently operational, but ...

The error message "Unable to access property 'slideHandler' of null in react-slick" is displayed

My current component utilizes two sliders in total (4 in combination) - one for horizontal carousel and the other for vertical, based on screen size. On smaller devices, it works perfectly fine, but on larger screens, it renders initially but crashes when ...

Having trouble deleting the value and deselecting the checkbox item?

Feeling a bit confused about a coding issue I'm facing. The problem lies in the categories listed in my database, which I fetched and used to create a post. Now, I'm attempting to edit that post. The categories are in checkbox format, where check ...

Uncover the origin of this tag by identifying the Material UI component responsible for its

Can anyone help me identify the specific React.Component that is responsible for generating this tag? https://i.stack.imgur.com/QwVsV.png Currently, I am utilizing a styled component in my code: import { styled } from '@mui/material/styles'; c ...

Contrasting ./ and $ in React project module imports

The creator of this particular project has utilized a different path to import a component: import { client } from '$lib/graphql-client' I'm curious: What is the significance of the $ symbol in this case? How does it differ from something ...

Is it possible to invoke an action within a reducer function?

I'm attempting to trigger an action in the redaction process and struggling to grasp the concept. ... import { loaderStart, loaderStop } from '../actions/loaders'; const loaders = dispatch => ({ loaderStart: text => dispatch(loader ...

The dynamic routing feature in React fails to function properly after the application is built or deployed

I'm facing an issue with getting a React route to function properly in the build version of my app or when deployed on Render. Here are the routes I have: <Route path="/" element={userID ? <Home /> : <Login />} /> <Route ...

Restrictions on file sizes when using multer for file uploads

I am currently working on a file uploader that needs to support various file types, such as images and videos. My goal is to apply different maximum file sizes for images (10MB) and videos (100MB) using a single instance of Multer, a middleware designed fo ...

How can I retrieve file input values in angularjs?

Currently, I am working on a simple application in AngularJS with the Slim framework. This application includes a form where users can input data such as their name, categories, currency, and an image file. While I am able to successfully retrieve data fro ...

In JavaScript, alert a message once all images have been clicked

I'm encountering a small issue with my javascript code. I am developing a game for a school project where the objective is to click (remove) fish using a fishing rod. However, the game does not have an end condition set up, so players cannot win. Belo ...

Why am I encountering a warning about dangerouslySetInnerHTML and receiving empty content in Next.js?

First and foremost, I am aware that nesting <p> tags is not recommended. I have developed a Next.js application wherein one of my components sets rich text HTML in the following manner: <Typography dangerouslySetInnerHTML={{ __ ...

Locate the point at which the two strings no longer match in their indices

Consider having 2 strings: var a = "abcdef", b = "abcdefgh"; I am searching for the first index where the complete match is broken without needing to iterate over both strings and compare each character with a loop. In this instance, I need to identify ...

Error: Missing provider for MatBottomSheetRef

While experimenting in this StackBlitz, I encountered the following error message (even though the MatBottomSheetModule is imported): ERROR Error: StaticInjectorError(AppModule)[CountryCodeSelectComponent -> MatBottomSheetRef]: S ...

Expand the accordion to reveal all the content

I'm facing an issue with my accordion where a scrollbar appears in every content section. To fix this, I tried setting overflow: hidden in the CSS: .ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; overflow: hidd ...

Passing ngModel from controller to directive in AngularJS

I'm currently working on a project that involves a controller with an attribute directive nested inside of it. This directive requires access to the ngModel of its parent controller. For more context, feel free to check out this Plunkr. Issue at Han ...

Leveraging environment variables in a 'use client' module within a Next.js application

I am facing the issue of not being able to access my .env variables such as GraphQL URL and access token in a 'use client' Apollo context wrapper component that is rendered client-side. Is there any solution for this in Next.js v13? Here is the ...

Create a dynamic effect by adding space between two texts on the page

const Button = () => { const options = ['test1', 'test2', 'test3']; return ( <div style={{ position: 'absolute', left: '8px', width: 'auto', flexDirection: 'row' ...

Dividing a sentence by spaces to isolate individual words

Recently, I encountered a challenging question that has me stuck. I am working on creating an HTML text box where the submitted text is processed by a function to check for any links. If a link is detected, it should be wrapped in anchor tags to make it cl ...

Is there a way to retrieve the dynamically generated text content of an element using document.write?

I am encountering an issue similar to the following: <div id="myDiv"><script>document.write('SOMETHING');</script></div> My goal is to extract the content inside the script tag, which in this case is "SOMETHING" ...

Is it advisable to supply the top-tier image quality for the next.js Image component?

Is it possible that providing 100% JPGs or 2x sized PNGs to the Image component could impact website performance and SEO in the long run? I've noticed that when supplying optimized images with reduced quality and size, the actual image displayed on th ...