1

I have users and jobs collection in my firebase and I want to update the field last_job_posted_date and job_count in the users. I looped every jobs by userId to get the total jobs and the last_job_posted_date. Now my problem is it is not updating. I found out that it executes first the batch.commit() before looping.

async testUpdateUserData() {
          this.batch = this.db.firestore.batch();
          await this.db.collection('users', ref => ref
        .where('role', '==', 'employer').limit(20)).get().subscribe(  async usersSnapshot => {

      usersSnapshot.forEach(async (userDoc) => {
        const userId = userDoc.id;

        //fetch data from the "jobs" collection
         await this.db.collection('jobs', ref => ref
        .where('uid', '==', userId)).get().subscribe(  async jobsSnapshot => {
          let lastJobPostedDate: Date | null = null;
          let jobCount = 0;

          jobsSnapshot.forEach(async (jobDoc) => {
            // Process each document and update variables
            const jobData = jobDoc.data();
            if(!lastJobPostedDate || (jobData.created_at > lastJobPostedDate)){
              lastJobPostedDate = jobData.created_at;
            }
            jobCount++;
          });

          //Prepare the updated data for the user document
          const updatedData = {
            last_job_posted_date: lastJobPostedDate,
            job_count: 0
          };

          //Create a batched write operation for each user document
          const docRef = this.db.collection('users').doc(userId).ref;
          await this.batch.update(docRef, updatedData);

        
        });
      });
      await this.batch.commit().then(() => {
        console.log("committed batch write to firestore!")
        // reset batch so it can be used again
        this.batch = this.db.firestore.batch();
        console.log('Batch update completed successfully');
      }).catch((error) => {
          console.error('Error performing batch update', error);
      });     
    });
  }
  • Because you are creating another async call in the callback which JavaScript doesn't track `.get().subscribe( async jobsSnapshot => {` – user16967562 May 18 '23 at 09:13
  • Why are you using `.subscribe`, it makes no sense? Get the data once. – user16967562 May 18 '23 at 09:16
  • @user16967562 I do not know, I'm just a beginner in javascript. I just copied the code somewher. Can you give me a sample code on how to do it correctly? – Anonymous Coder May 18 '23 at 11:31
  • Using `await` in a `forEach` block doesn't work. See https://stackoverflow.com/questions/37576685/using-async-await-with-a-foreach-loop for alternatives, of which `for (... of...)` seems the most likely for you – Frank van Puffelen May 18 '23 at 13:26

0 Answers0