Reputation: 440
I used firebase.auth().setPersistence(firebase.auth.Auth.Persistence.LOCAL) however log in is NOT persisted on page refresh or close/reopen. It is just there and do nothing.
Anyone can help with it, please ...
export const loginUser = (creds) => (dispatch) => {
dispatch(requestLogin(creds))
firebase.auth().setPersistence(firebase.auth.Auth.Persistence.LOCAL)
.then(() => {
// New sign-in will be persisted with local persistence.
return firebase.auth().signInWithEmailAndPassword(creds.username, creds.password)
.then(() => {
var user = firebase.auth().currentUser;
if (user.emailVerified) {
localStorage.setItem('user', JSON.stringify(user));
// Dispatch the success action
dispatch(fetchFavorites());
dispatch(receiveLogin(user));
} else {
firebase.auth().signOut()
alert('Your email can not be verified.')
}
})
.catch(error => { dispatch(loginError(error.message)); alert(error) })
})
.catch(error => { alert(error) });
}
Upvotes: 3
Views: 2414
Reputation: 440
OMG. It crunched me a full 6 hours :). 2hrs before yelling for rescue here then 4hrs after to fully solve it myself and clean code throughout react => redux => firebase.
Below is the full round solution and will work to
Step by step:
firebase.auth().setPersistence(firebase.auth.Auth.Persistence.LOCAL)
in firebase configuration. Do not use it with signup, login functions. You want it to umbrella above your whole web/app auth, not piece by piece of inner codeBelow is my firebase configuration full code. You can see that I set persistence condition above everything else
import { config } from './config';
import firebase from 'firebase';
firebase.initializeApp(config);
firebase.auth().setPersistence(firebase.auth.Auth.Persistence.LOCAL);
const settings = {timestampsInSnapshots: true};
firebase.firestore().settings(settings);
export const firestore = firebase.firestore();
export const firebasestore = firebase.firestore;
export const auth = firebase.auth();
export const fireauth = firebase.auth;
export { firebase };
Remember up till now we already have login persisted BUT IT IS ONLY WITH GOOGLE. ~ 4hrs ago I was still thinking that is enuf, lmao :). Well need to go and make react and redux knows about this info, update state for log in, update state for user, update state for data fetching for this current user, update data render for this current user in all UI components.
Go to the component which manages authentication. My file is "HeaderComponent.js". It is the navigation bar where the login button is.
Here is what I include in "HeaderComponent.js" to update for redux:
import { connect } from 'react-redux';
import { fetchFavorites, receiveLogin } from '../redux/ActionCreators';
const mapStateToProps = state => {
return {
favorites: state.favorites,
auth: state.auth,
}
}
const mapDispatchToProps = (dispatch) => ({
fetchFavorites: () => dispatch(fetchFavorites()),
receiveLogin: (user) => { dispatch(receiveLogin(user)) },
});
Explanation:
I reinforced web security with request to satisfy email verification before user can be logged in. This is optional
componentDidMount() {
firebase.auth().onAuthStateChanged((user) => {
if (user) {
if (user.emailVerified) {
localStorage.setItem('user', JSON.stringify(user));
// Dispatch the success action
this.props.fetchFavorites();
this.props.receiveLogin(user); // update state. isAuthenticated=true, user=currentUser
} else {
firebase.auth().signOut()
alert('Your email can not be verified.')
}
} else {
// User is signed out
firebase.auth().signOut()
}
});
}
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Header));
Explanation:
componentWillUnmount() {
this.props.logoutUser();
}
Upvotes: 2