React + Firestore:从查询中返回一个变量

IT技术 javascript reactjs firebase google-cloud-firestore
2021-04-09 07:22:58

我目前正在学习 React 和 Firestore,但有点卡住了。我正在尝试通过搜索用户名从 Firestore 集合中检索用户名。

以下代码在“课程”地图中执行以创建列表。

{lesson.post_author && findName(lesson.post_author)}

以下代码是 findName 函数。

let findName = uid => {
    firebase.firestore().collection("users")
      .where('uid', '==', uid)
      .get()
      .then(querySnapshot => {
          console.log(querySnapshot.docs[0].data().name);
    });

  };

目前, findName 函数会将所有名称成功记录到控制台。我已经更改了代码,以便能够在 firestore 调用之外控制台日志,但这会返回一个在控制台中挂起的Promise。

代码的目标是返回名称而不是列表中的 uid。

任何帮助将非常感激。谢谢!

2个回答

正如其他人所解释的那样,您无法返回该值,因为它是从 Firestore 异步加载的。到您return运行时,数据尚未加载。

在 React 中,您通过将数据置于组件的状态中并从那里使用它来处理此问题。如果您这样做,您的渲染方法可以简单地从状态中提取它,例如:

{lesson.post_author && findName(lesson.post_author_name)}

(以上假设lesson间接来自国家。

如果我们假装只有一节课,并且您在状态中直接拥有这些值,那就更容易了:

{state.post_author && findName(state.post_author_name)}

现在我假设你已经有了post_author并且你只需要查找作者的名字。这意味着在componentDidMount您将加载附加数据并将其添加到状态中/之后的某处

componentDidMount() {
  firebase.firestore().collection("users")
    .where('uid', '==', this.state.uid)
    .get()
    .then(querySnapshot => {
      this.setState({ post_user_name: querySnapshot.docs[0].data().name });
  });
}

现在数据的加载仍然是异步发生的,所以调用setState()componentDidMount完成后的一段时间发生但是 React 意识到改变状态可能需要刷新组件,所以它通过重新setState()渲染来响应调用

请注意,我强烈建议使用每个用户的 UID 作为users. 这样您就不需要查询,只需直接查找即可:

componentDidMount() {
  firebase.firestore().collection("users")
    .doc(this.state.uid)
    .get()
    .then(doc => {
      this.setState({ post_user_name: doc.data().name });
  });
}

我正在尝试通过搜索用户名从 Firestore 集合中检索用户名。

这是通过对 Firestore 引用使用异步.get方法来实现的在您的情况下,您可能有一usersfirebase.auth().currentUser.uid命名文档。

var userRef = firebase.firestore().collection('users').doc(users.uid);
userRef.get().then(function(doc) {
    if (doc.exists) {
        console.log("Users first name is:", doc.data().firstName);
    } else {
        // doc.data() will be undefined in this case
        console.log("No such document!");
    }
}).catch(function(error) {
    console.log("Error getting document:", error);
});