¿Por qué onSnapshot() se ejecutó en último lugar?

Resuelto Lam My Ky - Kailey asked hace 54 años • 0 respuestas

Quiero crear una función de Registro en Javascript que cargue la información de registro en Firebase Firestore y la registre en la consola cuando finalice la carga.

  • Quiero que el flujo de trabajo de mi consola sea así: registrar datos de Firestore a la consola -> establecer elemento en localStorage -> alerta -> redirigir a otra página
  • Pero de alguna manera el flujo es el siguiente: configure el elemento en localStorage -> alerta -> redirigir a otra página (y nunca registre datos de Firestore en la consola)
  • Cuando omito la redirección, el flujo es: configurar el elemento en localStorage -> alerta -> registrar datos de Firestore a la consola

También quiero incluir la identificación de usuario en los datos cargados en Firestore. ¿Cómo puedo obtenerlo?

Explíqueme por qué sucedió esto y qué puedo hacer para lograr el resultado deseado. Gracias por tu

Fragmento de código

import { createUserWithEmailAndPassword } from 'https://www.gstatic.com/firebasejs/10.7.2/firebase-auth.js';
import { collection, onSnapshot, addDoc } from "https://www.gstatic.com/firebasejs/10.7.2/firebase-firestore.js";

import { auth, isArtist, firestore } from "./firebase-config.js";

// if isArtist: profile(publish, no playlist)
// if !isArtist: profile(no publish, playlist)
isArtist();

const Register = async (auth, email, password) => {
  let isChecked;
  let info;
  try {
    const userCredential = await createUserWithEmailAndPassword(auth, email, password);
    isChecked = true;
  } catch (error) {
    isChecked = false;
    info = error.code;
  }
  return {
    info, 
    isChecked,
  };
};

const RegisterPage = () => {
    document.getElementById("btn-register").onclick = async () => {
        let email = document.getElementById('email-register').value;
        let password = document.getElementById('password-register').value;
        let username = document.getElementById('username-register').value;
        let isArtist = localStorage.getItem("isArtist");
        // let user = userCredential.user;

        const isSuccess = await Register(auth, email, password);
        // Inheritance of OOP: isChecked is a local variable of Register
        // After assigning Register to isSuccess -> isSuccess can use isChecked
        if (isSuccess.isChecked) {
            // Compile acc info
            const data = {
              dateRegistration: Date.now(),
              // userID: user.uid,
              email,
              username,
              isArtist,
            };
            // Upload acc info to Firestore
            const colRef = collection(firestore, "accounts");
            addDoc(colRef, data)
              .then(() => {
                // Kiểm tra Firestore
                onSnapshot(colRef, (snapshot) => {
                  const output = [];
                  snapshot.docs.forEach((doc) => {
                      output.push({...doc.data()});
                  });
                  console.log(output);
                });

                localStorage.setItem("email", email);
                alert("Register successful");
                window.location.href = "home.html";
              })
              .catch((error) => {
                alert("Error uploading data to Firestore:", error);
              })  
        } else {
            alert("Register fail");
        }
    };
};

RegisterPage();
Lam My Ky - Kailey avatar Jan 01 '70 08:01 Lam My Ky - Kailey
Aceptado

Esto se debe a que JavaScript no espera que se onSnapshot()complete la ejecución de la devolución de llamada pasada antes de pasar a la siguiente línea.

Dado que, en su caso, desea obtener los documentos de las colecciones solo una vez, debe utilizar el getDocs()método asincrónico de la siguiente manera. Observe cómo gestionamos la asincronicidad de las diferentes llamadas a los métodos de Firebase usando await:

// ...
if (isSuccess.isChecked) {
  // Compile acc info
  const data = { ...};
  // Upload acc info to Firestore
  const colRef = collection(firestore, "accounts");
  await addDoc(colRef, data); // Your function is async, so use await!

  const snapshot = await getDocs(colRef);  // See the await keyword

  const output = [];
  snapshot.docs.forEach((doc) => {
    output.push({ ...doc.data() });
  });
  console.log(output);

  localStorage.setItem("email", email);
  alert("Register successful");
  window.location.href = "home.html";
} else {
  alert("Register fail");
}
Renaud Tarnec avatar Feb 16 '2024 09:02 Renaud Tarnec