在使用Firebase进行身份验证后,无法在重新基础syncState中访问状态

时间:2017-09-18 23:16:09

标签: javascript reactjs firebase firebase-realtime-database firebase-authentication

我有一个带有以下浅层数据库模型的React应用程序,连接到Firebase:

{
  "users": {
    "userid1": {
      "Full name": "Patrick Bateman",
    },
  },
  "posts": {
    "userid1": {
      "post-1": {
        text: "Lorem ipsum",
        ...
      },
      "post-2": {
        text: "Cats sure are swell",
        ...
      },
    },
    "userid2": {
      ...
    }
  }
}

在React中,我正在使用re-base库的syncState()来获取初始内容并保持本地状态和firebase同步。 在重新基础文档和示例中,他们在syncState()中使用componentDidMount。这是有道理的,但我不想同步所有的firebase帖子;只有属于用户的那些,所以我的直觉是做这样的事情:

componentDidMount() {
  this.refs = base.syncState(`posts/${this.state.uid}`, {
    context: this,
    state: 'posts',
  });
}

这里的问题是this.state.uid在生命周期的这个阶段是null

我的问题是:当我调用syncState时如何访问uid?

以下是我的其余代码供参考,show auth:

init() {
  // I need the uid here!!!!!! 
  console.log(this.state.uid); // null
  this.refs = base.syncState(`posts/${this.state.uid}`, {
    context: this,
    state: 'posts',
  });
}

componentDidMount() {
  this.unsubscribe = firebase.auth().onAuthStateChanged((user) => {
    if (user) {
      window.localStorage.setItem(storageKey, user.uid);
      this.setState({
        uid: user.uid,
        user
      });
    } else {
      window.localStorage.removeItem(storageKey);
      this.setState({
        uid: null,
        user: null,
        posts: null,
      });
    }
  });

  // re-base firebase sync
  this.init();
}

componentWillUnmount() {
  base.removeBinding(this.ref);
  this.unsubscribe();
}

authenticate = (provider) => {
  if (provider === 'twitter') {
    provider = new firebase.auth.TwitterAuthProvider();
  } else if (provider === 'google') {
    provider = new firebase.auth.GoogleAuthProvider();
    provider.addScope('https://www.googleapis.com/auth/plus.login');
  }

  firebase.auth().signInWithPopup(provider).then((authData) => {
    // get the of the firebase.User instance
    const user = authData.user;
    // Set local storage to preserve login
    window.localStorage.setItem(storageKey, user.uid);
    // Set the state of the current user
    this.setState({
      uid: user.uid,
      user,
    });
  }).catch(function(error) {
    console.log(error);
  });
};

使用上面的代码,我的应用程序正确创建了本地状态:

State
  posts: {
    post-1: {
      ...
    }
  }

但是在firebase上,由于uid不可用,因此预计会将其添加到null用户。

database: {
  posts: {
    null: {
      post-1: {
        ...
      }
    }
  }
}

1 个答案:

答案 0 :(得分:0)

您可以在状态设置后调用this.init()this.setState有第二个参数是回调。这样您就可以确保uid不会为空。

示例

this.setState({
  uid: user.uid,
  user
}, () => {
  this.init();
});