Firebase身份验证,React:身份验证偶尔失败

时间:2020-10-16 06:14:34

标签: reactjs firebase firebase-authentication

我有一个组件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 。有趣的是,发帖请求仍在进行。

无论成功还是失败,我都已登录,并且我只能假设this.state.userDetails.uid评估为null表示auth状态已过期,或者该组件在为userDetails分配值之前正在呈现?
我遇到的问题是,我无法确定这是异步问题还是auth状态持久性问题,而且我也无法弄清楚为什么这是偶发性故障。

1 个答案:

答案 0 :(得分:1)

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

File A
如果

let user = auth().currentUser.uid; 在访问时没有用户登录(或者不确定是否是这种情况),则为null。 API documentation中对此进行了介绍。

理想情况下,您永远不要使用currentUser,而应依靠currentUser提供的状态。我在this blog post中对此进行了详细讨论。如果确实需要使用onAuthStateChanged,则应在引用其属性之前将其检查为null。

您还应该知道,最好通过使用侦听器来获取ID令牌。呼叫为onIdTokenChanged,其工作方式类似于身份验证状态监听器。

还请记住,currentUser是异步的,不会立即设置状态。您的Firestore查询可能无法立即获得所需的状态。