Reputation: 409
I am using Firebase.auth() to authenticate a login with Google Firebase then I retrieve the UID and send it to my Redux Store. The UID is not being sent to the store unless I navigate to the next page then return to the login page. It seems my order of operations is off, how can I get the UID in my Redux store without haveing to re-login/ refresh the page.
class Home extends React.Component {
constructor(props) {
super(props);
this.state = {
id: ''
}
}
id (value) {
this.props.id(value);
}
handleLogin = (load) => {
const { email, password } = this.state
Firebase.auth()
.signInWithEmailAndPassword(email, password)
.then(async cred => {
return db.collection('users').doc(cred.user.uid).set({
test: 'test'
})
})
.then(() => this.props.navigation.navigate('AddProfiles'))
.catch(error => console.log(error))
const currentUser = firebase.auth().currentUser;
const userId = currentUser["uid"];
this.setState({
id: userId
})
this.props.id(this.state.id);
}
<TouchableOpacity style={styles.signupbutton}>
<Button
color='white'
title="Log in"
onPress={(payload) => this.handleLogin()}
/>
</TouchableOpacity>
const mapStateToProps = (state) => {
return {
counter: state.counter,
value: state.id
};
}
const mapDispatchToProps = dispatch => {
return {
id: (value) => dispatch({ type: 'id', payload: value })
}
};
export default connect(mapStateToProps, mapDispatchToProps)(Home)
Upvotes: 0
Views: 797
Reputation: 52397
Right now, the code starting with the line const currentUser
is running before the signInWithEmailAndPassword
completes, since signInWithEmailAndPassword
is an asynchronous function. The reason that it works on refresh is at that point, firebase.auth().currentUser
has a value, so
You can move your code inside the then
block so that it runs only when the function is complete. It'll look something like this (untested, because I don't have the rest of your code):
handleLogin = (load) => {
const { email, password } = this.state
Firebase.auth()
.signInWithEmailAndPassword(email, password)
.then(async cred => {
this.setState({
id: cred.user.uid
})
this.props.id(cred.user.id);
return db.collection('users').doc(cred.user.uid).set({
test: 'test'
})
})
.then(() => this.props.navigation.navigate('AddProfiles'))
.catch(error => console.log(error))
}
Note that setState
is also asynchronous, so calling this.props.id(this.state.id);
right after setState
is likely to fail on the first run.
Although the above should fix the immediate issue, I'd suggest onAuthStateChanged
: https://firebase.google.com/docs/auth/web/start#set_an_authentication_state_observer_and_get_user_data
This way, you can do your sign in and set the Redux state based on its value or run the same code to set the Redux value when the user just returns to a page. It'll probably lead to a more robust situation than tying everything to signInWithEmailAndPassword
Upvotes: 1