Home > Net >  Can't make firestore to get only docs from logged user id
Can't make firestore to get only docs from logged user id

Time:01-09

how are you?

This is my first question here, I am an UX Designer and I'm pretty new to working with Firebase.

I've been trying to develop a system on webflow integrated with firebase using javascript and the firebase SDK to a personal project and got stuck with this problem:

I have managed to create the authentication system, the signup system and everything is working as it should.

However, when I try to fetch data from Firestore userdata collection, I am not being able to get the current user id and pass it to the WHERE string on my query.

If I run the query without the WHERE, it works perfectly bringin me all the documents in the userdata collection, but when I try to do it only for a specific user, it fails.

I already tried a lot of things which I think wasn't the right method to do this, the JavaScript below was my last attempt, but I've been stuck on this for 8 hours now, and I'm in hope someone can help me, I think I'm just too newbie on this and can't understand how to pass the id variable into the query.

Can anyone help?

here is the link to the project: https://poupei.webflow.io/ just click Criar conta to create an account, you can use a fake email and 6 digit password and then login.

  // Import the functions you need from the SDKs you need
import { initializeApp } from "https://www.gstatic.com/firebasejs/9.4.0/firebase-app.js";
import { getAuth, onAuthStateChanged, signOut } from "https://www.gstatic.com/firebasejs/9.4.0/firebase-auth.js";
import { getFirestore, collection, getDocs, query, where, doc } from "https://www.gstatic.com/firebasejs/9.4.0/firebase-firestore.js"


// TODO: Add SDKs for Firebase products that you want to use
  // https://firebase.google.com/docs/web/setup#available-libraries

  // Your web app's Firebase configuration
 const app = initializeApp({
    apiKey: "AIzaSyAZUIyxf4Lsw6D9JOzVuNslsGJ8gXkPBVY",
    authDomain: "poupei-app.firebaseapp.com",
    projectId: "poupei-app",
    storageBucket: "poupei-app.appspot.com",
    messagingSenderId: "837432279066",
    appId: "1:837432279066:web:119bc86e42fb87ac17d1a3"
});

  // Initialize Firebase
  const auth = getAuth()
  const db = getFirestore();
  onAuthStateChanged(auth, (user) => {
  if (user) {
    // User is signed in, see docs for a list of available properties
    // https://firebase.google.com/docs/reference/js/firebase.User
    const userID = user.id;
    console.log("Logged In");
    console.log(userID);
    // ...
  } else {
    // User is signed out
    window.location.replace("https://poupei.webflow.io/");
  }
});

const q = query(collection(db, "userdata"), where("id", "==", userID));
const querySnapshot = await getDocs(q);
querySnapshot.forEach((doc) => {
  // doc.data() is never undefined for query doc snapshots
  console.log(doc.id, " => ", doc.data());
  const docs = doc.data();
   document.getElementById('nome').innerHTML = docs.nome;
   document.getElementById('sobrenome').innerHTML = docs.sobrenome;
   document.getElementById('email').innerHTML = docs.email;
   document.getElementById('saldo').innerHTML = docs.saldo;
});

 document.getElementById('logoutBtn').addEventListener('click', function(){
  signOut(auth).then(() => {
  // Sign-out successful.
  window.location.replace("https://poupei.webflow.io/");
}).catch((error) => {
  // An error happened.
});
});

</script>

´´´

CodePudding user response:

I think that the query doesn't know what userID is because you are declaring that variable inside authStateChange. Try to move the declaration of userID to global scope add a console.log() before executing the query to see if the userID is set correctly. Or just put the code that performs the query inside the onAuthStateChanged code so that you can use the userID.

CodePudding user response:

@Allennick has the cause of the problem correct in their answer, but the solution won't work.


Signing in to Firebase (as well as loading data from Firestore and most other modern cloud APIs) is an asynchronous operation. While the user is being signed in (or the data is being loaded) your main code continues to run. Then when the user is signed in, your callback code is executed.

It's easiest to see this flow by running in a debugger, or adding some logging:

console.log("Attaching auth state listener");
onAuthStateChanged(auth, (user) => {
  if (user) {
    console.log("Got user state");
  }
});

console.log("Starting database query");
const q = query(collection(db, "userdata"), where("id", "==", userID));
const querySnapshot = await getDocs(q);

When you run this code it logs:

Attaching auth state listener

Starting database query

Got user state

This is probably not the order you expected, but it perfectly explains why you're not getting the user data from the database: the query executes before the user is ever loaded.


The solution to this problem is always the same: any code that needs to react to the current user state, needs to be inside the onAuthStateChanged callback, be called from there, or otherwise synchronized.

The simplest fix is to move your database code into the callback, like this:

onAuthStateChanged(auth, (user) => {
  if (user) {
    const userID = user.id;

    //            
  •  Tags:  
  • Related