React + Firestore:从查询返回变量

时间:2018-11-29 01:18:36

标签: javascript reactjs firebase google-cloud-firestore

我目前正在学习React和Firestore,有点卡住了。我正在尝试通过搜索用户的uid从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 个答案:

答案 0 :(得分:1)

  

我正在尝试通过以下方式从Firestore集合中检索用户名:   搜索他们的uid。

这是通过在Firestore参考上使用异步.get method来完成的。就您而言,您可能有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);
});

答案 1 :(得分:0)

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

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

{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中文档的ID。这样一来,您无需查询即可直接进行查找:

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