【问题标题】:Data always log 0 if log the length when fetch data from firestore如果在从 firestore 获取数据时记录长度,则数据始终记录 0
【发布时间】:2022-01-04 10:01:19
【问题描述】:

我正在尝试从 firestore 获取数据,我的工作流程如下:

  • 创建一个数组,然后记录'users'集合的id

  • 通过检查上面数组中的值是否存在来检查用户是否存在,如果存在则直接登录,如果不存在则在firestore上创建新集合

但不知道我记录数据时如何正确显示,但是如果我记录长度,它总是显示0,当然每次比较都显示为假

这里是代码

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>
  );
}

这是的图片

我不知道我在哪里搞砸了,请帮忙,非常感谢你

【问题讨论】:

  • 我唯一看到的是你没有await你对getUser的调用,这是一个异步函数。这可能会导致竞争条件问题。
  • 我不明白@GaëtanBoyals,我试图不调用异步函数,但当我登录时结果仍然返回 0,但如果我记录数据,它会返回真实数据
  • 尝试在login.tsx 中放入await getUser(); 而不是简单的getUser();,第71 行,看看它是否有效。如果没有,我也帮不上什么忙,因为我没有发现任何问题。
  • 很高兴能帮上忙!
  • @GaëtanBoyals 听起来像是一个答案 Gaëtan ????能不能把它贴在下面,让系统也能看到问题已经回答了?

标签: javascript reactjs firebase google-cloud-firestore


【解决方案1】:

您在getUser 函数(在本例中为firebase)中调用了一个远程数据库,这是一个不可避免地需要比本地代码更长的执行时间的网络请求。

这会导致一个称为竞态条件的问题。您对getUser() 的调用下面的代码可能会在网络请求完成之前执行,从而导致不可预知的行为。

为防止这种情况发生,您需要等待网络调用完成,然后再处理任何进一步的指令。无论您是通过callbackspromises 还是async/await 语法都取决于您的喜好,但由于您已经使用async/await,您需要await 调用getUser(),下面是您的代码更正:

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>
  );
}

【讨论】:

    猜你喜欢
    • 2020-03-07
    • 1970-01-01
    • 2013-01-11
    • 1970-01-01
    • 2011-05-29
    • 1970-01-01
    • 2020-05-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多