Loop through a collection of unique identifiers for documents and establish event listeners in Firestore

Within my Vuex store, there is an action designed to retrieve a list of uids for followed users from the current user's Firestore UserDataCollection document. The action then processes each uid to extract data that will be displayed on the UI. While this process functions correctly using .get(), I am attempting to transition it to .onSnapshot() in order to receive real-time updates.

I have encountered difficulties while trying to incorporate .onSnapshot(). There seems to be a lack of resources online or in the Firebase documentation regarding the implementation of this method after iterating through the array of uids.

After experimenting by removing promises and substituting .get() with .onSnapshot(), I have not achieved success.

If anyone has insight on the correct way to integrate the Firestore .onSnapshot() listener into the provided code snippet, please share your expertise.

getCircle({state, commit}) {
  const circle = state.userProfile.circle
  let promises = circle.map(u => userDataCollection.doc(u).get())
  
    return Promise.all(promises)

    .then(querySnapShot => {
      let circleData = []
      if (querySnapShot.empty) {
        console.log("empty")
      } else {
        querySnapShot.forEach(doc => {
          let item = doc.data()
          circleData.push(item)
         }
        )
      }
      commit('setUserCircle', circleData)
    })
},

Edit based on response

To address feedback, I have integrated .onSnapshot within the forEach loop as demonstrated below. Although Vue devtools display the correct number of data entries in my Vuex store, they are all undefined.

getCircle({state, commit}) {
  const circle = state.userProfile.circle
  let promises = circle.map(u => userDataCollection.doc(u).get())
  
    return Promise.all(promises)

    .then(querySnapShot => {
      let circleData = []
      if (querySnapShot.empty) {
        console.log("empty")
      } else {
        querySnapShot.forEach(x => {
          let itemId = x.data().uid
          userDataCollection.doc(itemId)
            .onSnapshot((doc) => {
              let item = doc.data()
              console.log(doc.data())
              circleData.push(item)
          })   
          }
        )
      }
      commit('setUserCircle', circleData)
    })

Answer №1

The code snippet above demonstrates the execution sequence of commit and onSnapshot callback in a specific scenario. An example is provided with hardcoded data for clarity.

let promises = circle.map(u => userDataCollection.doc(u).get())

Promise.all(promises)
.then( querySnapShot =>  {
    var circleData = []
     querySnapShot.forEach( x  => {
        let itemId = x.data().uid
        userDataCollection.doc(itemId).onSnapshot(doc => {
            let item = doc.data()
            circleData.push(item)
            console.log("inside snapshot: ",circleData.length)
        })
    })
    console.log("outside foreach: ",circleData.length)
})

Upon running this code, the console output should resemble the following (tested on Node.js):

outside foreach:  0
inside snapshot:  1
inside snapshot:  2
inside snapshot:  3

If any changes are made in Firestore, an additional console log inside snapshot: 4 will be generated.

It is suggested that the commit statement might need to be positioned within the onSnapshot listener based on potential application logic considerations, although this recommendation is speculative given the available information.

Answer №2

Big thanks to all who contributed to finding a solution. By eliminating the .map and Promise and opting for an 'in' query, we were able to make it work. Check out the code snippet below:

 fetchData({status, dispatch}) {
   const data = status.userData.data

   collectionReference.where('__name__', 'in', data).onSnapshot(snap => {
    var processedData = []
    snap.forEach(document => {
      let entry = document.data()
      processedData.push(entry)
      dispatch('updateUserData', processedData)
    })
  })
},

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

What is the solution for - Uncaught TypeError: Cannot access the property 'scrollHeight' of an undefined element?

Could someone kindly assist me in resolving an issue? I recently encountered a problem with a script I have been using on the Chrome console. This script has been working perfectly fine for the past few days. However, today when I ran it, I started receiv ...

Utilize Page.evaluate() to send multiple arguments

I am facing an issue with the Playwright-TS code below. I need to pass the email id dynamically to the tester method and have it inside page.evaluate, but using email:emailId in the code throws an undefined error. apiData = { name: faker.name.firstNa ...

Dealing with onChange value in a date in reactjs is a common challenge that developers

I'm currently working on a basic date input component in React, but I've run into an issue when trying to change the value. Every time I update it, it always displays "1970-01-01". If anyone has any suggestions on how to fix this problem, I woul ...

Is Moment.js displaying time incorrectly?

When using moment.tz to convert a specific date and time to UTC while considering the Europe/London timezone, there seems to be an issue. For example: moment.tz('2017-03-26T01:00:00', 'Europe/London').utc().format('YYYY-MM-DD[T]HH: ...

Is there a specific method to access a JSON file with (js/node.js)?

Searching for a way to access user information stored in a JSON file using the fs module in node.js. Specifically looking to read only one user at a time. app.get("/1", function(req, res) { fs.readFile("users.json",function(data, err){res.write(data)}} W ...

Perform a toggle action on the first row when clicking within the current row using Jquery

I've been grappling with the idea of creating a function that can display and hide a comment field when a button is clicked. The challenge here is that there are multiple line items with their own comment boxes. I want to find a way to achieve this wi ...

Error: Document's _id field cannot be modified

I am new to both MongoDB and Backbone, and I find it challenging to grasp the concepts. My main issue revolves around manipulating attributes in Backbone.Model to efficiently use only the necessary data in Views. Specifically, I have a model: window.User ...

Update the directive automatically whenever a change occurs in the root scope property

I am facing an issue with a directive that generates a random number. My goal is to reload or refresh this directive when a checkbox is toggled. Below is the code I have been using, but unfortunately, it's not working as expected. var app = angular. ...

Is there a way to rearrange the selectpicker selection based on the user's choice?

I'm in the process of setting up a selectpicker that allows users to choose multiple options from a dropdown list. The challenge is that the values extracted by my backend need to be in the order of user selection, rather than the original order of th ...

Customizing the appearance of React Navigation StackNavigator through background color changes and styling

Recently delving into React Native, I've managed to create a basic app with three different scenes. Initially, I used Navigator for navigation purposes, but found it to be sluggish and decided to give React Navigation (found at https://reactnavigation ...

Link rows to dictionary keys and show their corresponding values

In my React component, I have a list of dictionaries stored in the props as follows: console.log(fruits): [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…} ] The dictionary entries are: 0: name: 'Apple' color: 'Red&apos ...

A guide to setting an href using variable values in jQuery through manual methods

I have a datepicker set up where each day, month, and year is stored in a variable. I then display this information in the desired format. Below is the jQuery code: jQuery(document).ready( function($){ alert('alert function'); var txtFr ...

What is the most effective way to import and load three-orbitcontrols?

Has anyone tried implementing the OrbitControls function in conjunction with ReactJS? I have included a snippet of the code below: import React, { Component } from 'react'; import 'tachyons'; import * as THREE from 'react'; im ...

Locate all inputs containing a special attribute name, wherein a portion of the name corresponds to a JavaScript variable

$("td[id^='td' + myvar + '_']") Can someone help me with a solution to substitute the static value of 0 in this code snippet with the dynamic variable myvar? Thanks! ...

Show and hide components in React by simply clicking on them

I'm looking to achieve the following: If the component is visible, clicking away from it should hide the component. If the component is hidden, clicking on it (or any area that it would occupy if visible) should show the component. Is there a way to ...

Feature for jotting down notes, creating a break between lines without any information present

I'm currently working on implementing a note-taking feature for my web application. However, I have encountered two issues: Firstly, I am struggling to identify line breaks within the text. While I can hardcode text with line breaks, when a user clic ...

Angular Flot Chart Resizing: A Guide to Dynamic Chart S

I have successfully integrated a Flot chart into my HTML using an Angular directive. Here is how it looks: <flot id="placeholder" dataset="dataset" options="options" height="300px" width="100%" style="width:100%;" ng-disabled="graphLoading" ng-class="{ ...

A guide on successfully handling errors while utilizing S3.getsignedurlpromise() in node.js

I am faced with a challenge in my project involving a node.js server that downloads images from an s3 bucket and serves them to a React client. The issue arises when the wrong file key is sent to the S3 client, as I want to handle this error gracefully by ...

Angular2 Error: Cannot have two identifiers with the same name, 'PropertyKey' is duplicated

I am currently developing an application with angular2 using angular-cli. Unfortunately, angular-in-memory-web-api was not included by default. After some research, I manually added the line "angular-in-memory-web-api": "~0.1.5" to my ...

Utilizing a Vue mixin to generate HTML elements and then attach them to a specified

I am looking to utilize a mixin to locate a referenced Node and then add some HTML content to it using Vue for data insertion. const Tutorial = guide => ({ mounted() { this.guide = guide; this.html = Vue.compile(`<p>Test</p ...