Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

450
Visualizações
Why is Firebase Query [ ] despite async/await?

I'm still struggling to understand how to extract values from a Firestore Query and put them into a global variable. I (now) understand that the asynchronous nature means that code isn't executed in the order that it is written. But, why is user still undefined in the following code block despite the await keyword inside of an async function? I understand (based on this question) that await should be applied only up to get(), otherwise there may not be values to iterate over.

My question is similar to this, but I run into the same issue as the comment and it looks like the question was never marked as answered. It is also similar to this, but pushing all gets to a Promise and then resolving that promise still didn't assign the data to a variable. It just printed an empty array.

I can print the variable, so my question is about assignment, I think. This function is a handler for an Intent in DialogFlow. I strongly prefer to have the data available outside of the call to the db. Adding to agent responses in a call to firestore doesn't always add the text to the agent, so I'd like to avoid that.

async function loginHandler(agent){     
     username = agent.parameters.username.name;      
     password = agent.parameters.password;

        const user = await db.collection("users")
                    .where("name","==",username)
                     .where("password","==",password)
                     .limit(1)
                     .get()
                     .then(querySnapshot =>{
                        querySnapshot.forEach(docSnapShot =>{
                            return docSnapShot.data();
                            //console.log.(docSnapShot.data()); //prints correct contents, so error is in programming logic
                            agent.add("Response"); // Would prefer to avoid this, but could refactor if I am fundamentally misunderstanding how to access Firebase data
                        })
                     })
                     .catch(error => console.log);
                                 

        console.log(user);      
       console.log("bort");  
}

Picture of Firestore to demonstrate that the correct data do exist:

enter image description here

about 4 years ago · Juan Pablo Isaza
3 Respostas
Responde à pergunta

0

forEach iterates the results but doesn't return anything, so your return inside there isn't doing what you'd expect (forEach returns void so you're returning the snapshot to a function that is returning void). You can create a local variable to hold the results you iterate and then return that:

const user = await db.collection("users")
                    .where("name","==",username)
                    .where("password","==",password)
                    .limit(1)
                    .get()
                    .then(querySnapshot =>{
                        // Set up an empty array to return later
                        let data = []
                        querySnapshot.forEach(docSnapShot =>{
                            // Add each snapshot's data object to the array
                            data = [...data, ...docSnapShot.data()]
                        })
                        // Return `data` which will populate `user`
                        return data
                     })
                     .catch(error => console.log);
about 4 years ago · Juan Pablo Isaza Relatório

0

You might be able to split the code up. Return the data from the database first, then map over the data to extract the details, and then assign that result to the user variable.

async function loginHandler(agent) {

  username = agent.parameters.username.name;
  password = agent.parameters.password;

  // `await` the promise and assign it to
  // `querySnapshot`
  const querySnapshot = await db.collection('users')
    .where('name', '==', username)
    .where('password', '==', password)
    .limit(1)
    .get()
    .catch(error => console.log);
  
  const user = querySnapshot.docs.map(docSnapShot => {
    agent.add('Response');
    return docSnapShot.data();
  });

  console.log(user);

}

about 4 years ago · Juan Pablo Isaza Relatório

0

Have you checked what the correct answer is?

Please clarify whether you mean undefined as you say in the title, or empty array as you say in the text.

Your code looks correct to me. I would not expect the output of console.log(user) to be undefined. However, an empty list [ ] would be a perfectly reasonable answer.

Perhaps there is nobody in that collection with that username and password?

Have you tried removing the condition of equality of username and password? That should get you an element of the collection, if it is not entirely empty.

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda