Is there a way to ensure my program waits for Firebase's data retrieval before running a specific function?

As a newcomer to Next.js and Firebase, I embarked on creating a login system with roles recently. Leveraging Firebase Authentication, I stored account roles in Firestore and linked the authentication account with Firestore data by utilizing the UID as the Document ID.

Note: While uncertain if this is the optimal approach, I've been successful in retrieving data from a field by referencing the Document ID acquired through the UID.

The goal is to extract the account's role from Firestore and apply it within a function to redirect users to appropriate pages based on their role. The issue arises when my pushToPage() function executes before getData() retrieves the necessary information from Firestore.

This is the LogIn function, where I employ auth.onAuthStateChanged to obtain the user's UID:


var firebaseDocument = ' ';
var accountType = '';
var databaseRef = '';

function LogIn() {
    signInWithEmailAndPassword(auth, email, password)
      .then((response) => {
        sessionStorage.setItem('Token', response.user.accessToken);

        auth.onAuthStateChanged((user) => {
          if (user) {
            firebaseDocument = user.uid;
            databaseRef = doc(database, 'users', firebaseDocument);
          } else {
            console.log('User logged out');
          }
        });
      })
      .catch((err) => {
        console.log(err.code);
      });

    accountType = getData();
    pushToPage(accountType);
  }

The following is the getData function responsible for fetching the account role:

const getData = async () => {
    try {
      const docSnap = await getDoc(databaseRef);
      if (docSnap.exists()) {
        return docSnap.data().account_type;
      } else {
        console.log('Document does not exist');
      }
    } catch (e) {
      console.log(e);
    }
  };

This snippet showcases the pushToPage function which utilizes the accountType variable to determine the redirection destination:

const pushToPage = (accountType) => {
    if (accountType == 'management') {
      router.push('/accounts/management');
    } else if (accountType == 'dean') {
      router.push('/accounts/deans');
    } else {
      router.push('/accounts/faculty');
    }
  };

Upon running this code, besides experiencing delays due to awaiting the Firebase response, an error message surfaces:

Unhandled Runtime Error
FirebaseError: Expected first argument to collection() to be a CollectionReference, a DocumentReference or FirebaseFirestore

Oddly enough, I did not utilize collection() at any point.

I've attempted to research similar issues and concluded that integrating a .then() function or some form of Asynchronous Programming technique may be necessary. Unfortunately, comprehending these concepts proves challenging for me.

Any assistance provided here would be greatly appreciated. Thank you all.

Answer №1

After some consideration, I realized that the .then() function is no longer necessary. I decided to directly call the pushToPage() function from within the getData function.

const getData = async () => {
    try {
      const docSnap = await getDoc(databaseRef);
      if (docSnap.exists()) {
        accountType = docSnap.data().account_type;
        pushToPage(accountType);
      } else {
        console.log('Document does not exist');
      }
    } catch (e) {
      console.log(e);
    }
  };

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

Warning: npm is resolving peer dependency conflicts during the installation process

Upon running npm install for my React application, I encountered the following warnings in the logs. Despite that, the npm installation completed successfully and the dependencies were added under node_modules. My app even starts up without any issues. I ...

Display the data returned from a computed property PromiseResult using VueJS

After calculating the property shown below, it will output res, which is a Promise object. The reason I cannot place this script inside the created() or mounted() hook is due to the fact that this.selectedObject is null at that time. I am satisfied with t ...

send document through ajax

Having some trouble with this task. Here is what I've managed to put together so far: <input id="newFile" type="file"/> <span style="background-color:orange;" onClick="newImage()">HEYTRY</span> I know it's not much progress. ...

Exploring the Bounds of Mongodb's $within Query

I'm currently working on a geospatial query in mongodb using the $within operator. I have a collection entry with a location field containing: location: { bounds: { south_west: { lat: XX.XXXXXX, lng: XX.XXXXX }, north_east: { lat: XX.XXXXXX ...

When attempting to POST data in Laravel, a status of 419 (unknown) is returned and the data cannot be posted to the target URL

I am attempting to create a DOM event that triggers when a user clicks on a table row's header (th) cell, deleting the corresponding row from the database that populates the table. Previously, my code worked as expected without any framework. I simpl ...

Web-based client services

Context: An HTML file I'm working with takes in multiple parameters and utilizes JavaScript to dynamically render the content. The page pulls data from various local XML files for processing. For instance, accessing service.html?ID=123 displays info ...

Utilizing a function as a value in React state (setState) compared to defining state with constructor in a class and utilizing a state object

Can someone help me understand the concept of state in React better? I'm confused about the differences between these two implementations: This: class Todo extends ... { constructor (){ super() this.state = { ... } } } And This: class Todo extend ...

Function that recursively checks for the existence of an ID within a nested object structure

I need assistance in developing a function that can determine whether the link ID of an object or any of its children match a specific ID. For instance, if the link ID for Product paths is 51125095, the function should return true when this ID is passed in ...

Adjust the size of an HTML image for printing using a JavaScript window.print() function

On my website, I have a print option set up where specific elements are hidden using @media. How can I adjust the size of an image within the @media query when my JavaScript print function is triggered? I am able to modify a regular div element easily, but ...

What is the method for swapping out the <button> element with the enter key?

I have a webpage where users can post status updates, and other users can comment on these statuses by typing in the textbox and clicking the 'Reply' button. However, I would prefer to remove the button so users can simply press the enter key to ...

Node.js Express not inserting data with Mongoose when using form data

For the past two weeks, I have been struggling to post data to insert into a database using form-data. It consistently shows a 400 bad request error. Below is my code for server.js: require('./db.js') let express = require('express') ...

Retrieving text data in Controller by utilizing jQuery AJAX request

Text box and button for input <input type="text" class="form-control" name="ClaimNumber" placeholder="Enter a claim number" id="ClaimNumber" /> <button class="btn btnNormal" type="submit" id="btnSearch"> ...

I'm having trouble with getting my Bootstrap CSS and JS links to function properly

The paths for the Bootstrap CSS and JS files have been included in the code, but unfortunately, they are not working. Instead, I am getting the following errors in the console: GET http://127.0.0.1:5000/[https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist ...

Retrieve the visitor's IP address following the submission of an AJAX form

Currently, I am facing an issue with my HTML form and JavaScript method integration. Whenever a visitor submits the form, a JavaScript method is triggered which sends an AJAX request to a PHP file on my server. The problem arises when trying to retrieve ...

Autoprefixer in postcss fails to function properly within Next.js framework

Currently working with Next.js version 13. I noticed that postcss and autoprefixer come already integrated into the Next.js project setup. Despite adding browserlist to my package.json, I'm facing issues as the styles are not prefixed as expected. ...

Add elements to an array with express, Node.js, and MongoDB

I'm currently learning about the MERN stack and I'm working on creating users with empty queues to store telephone numbers in E.164 format. My goal is to add and remove these numbers from the queue (type: Array) based on API requests. However, I ...

Retrieving previous data following an AJAX request using the GET method in Laravel 5.5

I have encountered an issue while using two ajax calls on a single page. On one side, I am making an ajax post request to store data and submit color in a database called "color_store." On the other side, I am trying to retrieve all the colors from that ta ...

Displaying a progress bar while fetching data in Vue: A step-by-step guide

I am working on developing a progress bar using vue js and bootstrap for my desktop application. Within the template, I have the code that will generate the necessary markup: <div class="container-fluid p-0 vh-100" v-if="isLoading&quo ...

The JavaScript function for converting a date to a local string in the format of DD MMM YYYY is causing an error message in the browser console stating that it is not a valid function

I am encountering an issue with formatting a date string. The date is currently in the format 2021-03-31T00:00:00, and I need it to be displayed as 31 Mar 2021. In my TypeScript code, I attempted to use the following function: const formattedDate = i.Susp ...

Store live text field group in their respective index

I am working on a project that involves creating dynamic description textareas based on the value selected from a dropdown list. The dropdown list contains numbers 1 through 5, and for each number chosen, I need to generate corresponding textareas with ser ...