【问题标题】:Firebase auth, React: Auth sporadically failingFirebase 身份验证,React:身份验证偶尔失败
【发布时间】:2020-10-16 14:35:34
【问题描述】:

我有一个组件GigRegister - 它的功能之一是从集合中获取所有文档,并仅返回当前登录用户创建的文档:

      authListener() {
        auth().onAuthStateChanged(user => {
          if(user){
            this.setState({
              userDetails:user
            },
            () =>
            firebase.firestore().collection('gig-listing').onSnapshot(querySnapshot => {
              let filteredGigs = querySnapshot.docs.filter(snapshot => {
                return snapshot.data().user === this.state.userDetails.uid
              })
              this.setState({
                filterGigs: filteredGigs
              })
            })
            ) //end of set state
          } else {
            this.setState({
              userDetails:null
            })
            console.log('no user signed in')
          }
        })
      }

      componentDidMount() {
        this.authListener();
      }

这个组件的另一个功能是从用户那里捕获数据,然后将其发布到firebase,然后重定向到另一个组件。

      handleSubmit(e) {
        
        let user = auth().currentUser.uid;
        const gigData = {
          name: this.state.name,
          venue: this.state.venue,
          time: this.state.time,
          date: this.state.date,
          genre: this.state.genre,
          tickets: this.state.tickets,
          price: this.state.price,
          venueWebsite: this.state.venueWebsite,
          bandWebsite: this.state.bandWebsite,
          user: user
        };

        auth()
          .currentUser.getIdToken()
          .then(function (token) {
            axios(
              "https://us-central1-gig-fort.cloudfunctions.net/api/createGigListing",
              {
                method: "POST",
                headers: {
                  "content-type": "application/json",
                  Authorization: "Bearer " + token,
                },
                data: gigData,
              }
            );
          })
          .then((res) => {
            this.props.history.push("/Homepage");
          })
          .catch((err) => {
            console.error(err);
          });
      }

这就是问题所在。有时,该组件按预期工作,数据提交和重定向按预期工作。有时,我会点击提交,但会触发消息TypeError: Cannot read property 'uid' of null 。有趣的是,post 请求仍然存在。

我在成功和失败时都已登录,我只能假设 this.state.userDetails.uid 评估为 null 意味着身份验证状态已过期,或者组件在 userDetails 可以分配值之前呈现?
我的问题是我无法判断这是异步问题还是身份验证状态持久性问题,我也无法弄清楚为什么它是零星的失败。

【问题讨论】:

    标签: reactjs firebase firebase-authentication


    【解决方案1】:

    这行代码可能会给你带来麻烦:

    let user = auth().currentUser.uid;
    

    currentUser 如果在访问时没有用户登录(或者不确定是否是这种情况),则为 null。 API documentation 对此进行了介绍。

    理想情况下,您永远不应使用currentUser,而应依赖onAuthStateChanged 提供的状态。我在this blog post 中详细讨论了这一点。如果你确实需要使用currentUser,你应该在引用它的属性之前检查它是否为空。

    您还应该知道,最好也使用侦听器来获取 ID 令牌。调用是onIdTokenChanged,它的工作方式类似于身份验证状态监听器。

    还要记住setState 是异步的,不会立即设置状态。您的 Firestore 查询可能没有立即获得所需的状态。

    【讨论】:

    • 我用let user = this.state.userDetails.uid 替换了let user = auth().currentUser.uid,但不幸的是我遇到了同样的问题。我认为你是对的,这是一个 setState 问题,问题出在此处吗 - this.setState({userDetails:user})
    • 其实我也注意到了一个警告,上面写着Warning: Can't perform a React state update on an unmounted component. - 这可能是相关的吗?
    猜你喜欢
    • 2017-11-27
    • 1970-01-01
    • 2019-03-09
    • 1970-01-01
    • 1970-01-01
    • 2018-01-24
    • 2017-08-24
    • 2018-12-06
    相关资源
    最近更新 更多