Home > front end >  Data always log 0 if log the length when fetch data from firestore
Data always log 0 if log the length when fetch data from firestore

Time:01-05

I'm trying to fetch data from firestore, my workflow like this:

  • Create an array, then log the id of collection of 'users'

  • Check if user exist by check if the value exist on the above array , if exist, then login directly, if not create new collection on firestore

But don't know how when i log the data, it show correctly, but if i log the length, it always show 0, and of course the comparison show false everytime

Here is the code

export default function Login(props: LoginI) {
  const user = useRef<User>();

  const [userExist, setUserExist] = useState<boolean>(false);
  let ListUser: any[] = [];
 

  const {} = props;
  const addNew = () => {
    firestore()
      .collection("Users")
      .doc(user.current?.user?.email)
      .set({
        userInfo: { ...user.current },
        note: firebase.firestore.FieldValue.arrayUnion(),
      });
    // .then(() => console.log("success"));
  };
  const getUser = async () => {
    await firebase
      .firestore()
      .collection("Users")
      .get()
      .then((data) => {
        data.forEach((snapshot) => {
          ListUser.push(snapshot.id);   ====> //add user to local array
        });
      });
  };
  async function signIn() {
    // Get the users ID token

    const userInfo = await GoogleSignin.signIn();

    user.current = userInfo;
    getUser();
    console.log("firebaseList", ListUser);  ==> always return value
    console.log("firebaseList", ListUser.length); ==> alway return 0

    // ListUser = ListUser.concat(user.current.user?.email);

    ListUser.forEach((item) => {
      console.log("item", item);
      if (item === user.current?.user?.email) {
        setUserExist(true);
        return;
      }
      return;
    });
    console.log(userExist);
    

    // Create a Google credential with the token
    const googleCredential = auth.GoogleAuthProvider.credential(
      userInfo.idToken
    );

    // Sign-in the user with the credential
    return auth().signInWithCredential(googleCredential);
  }

  return (
    <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
      <Button
        onPress={() => {
          signIn();
        }}
      >
        <Text style={{ color: "white" }}>Login</Text>
      </Button>
    </View>
  );
}

Here is the pic of this enter image description here

I don't know where i get mess up, please help, thank you so much

CodePudding user response:

You are calling a distant database in your getUser function (in this case, firebase), a network request which will inevitably take longer to execute than your local code.

This leads to an issue called race condition. The code below your call to getUser() might be executed before the network request is completed, resulting in unpredictable behavior.

To prevent this, you need to wait for the network call to complete before treating any further instructions. Whether you do it via callbacks, promises or async/await syntax is up to your preferences but since you already use async/await, you need to await your call to getUser(), below is your code with the correction:

export default function Login(props: LoginI) {
  const user = useRef<User>();

  const [userExist, setUserExist] = useState<boolean>(false);
  let ListUser: any[] = [];
 

  const {} = props;
  const addNew = () => {
    firestore()
      .collection("Users")
      .doc(user.current?.user?.email)
      .set({
        userInfo: { ...user.current },
        note: firebase.firestore.FieldValue.arrayUnion(),
      });
    // .then(() => console.log("success"));
  };
  const getUser = async () => {
    await firebase
      .firestore()
      .collection("Users")
      .get()
      .then((data) => {
        data.forEach((snapshot) => {
          ListUser.push(snapshot.id);   ====> //add user to local array
        });
      });
  };
  async function signIn() {
    // Get the users ID token

    const userInfo = await GoogleSignin.signIn();

    user.current = userInfo;
    // the line below was missing an await
    await getUser();
    console.log("firebaseList", ListUser);  ==> always return value
    console.log("firebaseList", ListUser.length); ==> alway return 0

    // ListUser = ListUser.concat(user.current.user?.email);

    ListUser.forEach((item) => {
      console.log("item", item);
      if (item === user.current?.user?.email) {
        setUserExist(true);
        return;
      }
      return;
    });
    console.log(userExist);
    

    // Create a Google credential with the token
    const googleCredential = auth.GoogleAuthProvider.credential(
      userInfo.idToken
    );

    // Sign-in the user with the credential
    return auth().signInWithCredential(googleCredential);
  }

  return (
    <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
      <Button
        onPress={() => {
          signIn();
        }}
      >
        <Text style={{ color: "white" }}>Login</Text>
      </Button>
    </View>
  );
}
  •  Tags:  
  • Related