Firebase, реагировать и редукса ждать обновления магазина

У меня есть приложение React, подключенное к Firebase, я хочу проверять, вошел ли пользователь в систему при каждом обновлении страницы, отправке IS_SIGNED_IN действие, вот создатель действия:

export function checkAuth() {
return dispatch => {
    firebaseAuth().onAuthStateChanged((user) => {
        if (user) {
            dispatch(signedInAction())
        } else {
            dispatch(signedOutAction())
        }
    })
  }
}

Внутри редуктора я просто делаю логическое isAuthenticated в истину / ложь:

case ActionTypes.isSignedIn: {
    return Object.assign({}, state, {
        isAuthenticated: true
    })
}
case ActionTypes.isSignedOut: {
    return Object.assign({}, state, {
        isAuthenticated: false
    })
}

Поскольку я хочу проверить, вошел ли пользователь при загрузке приложения, я отправляю действие в componentDidMount (что неправильно я думаю):

class Main extends Component {

constructor(props) {
    super(props);
}

componentDidMount() {
    store.dispatch(checkAuth());
}

render() {
    return (
        <Provider store={store}>
            <Router>
                <Theme>
                    <Routes />
                </Theme>
            </Router>
        </Provider>
    );
  }
}

Это делает мой код, где я проверяю isAuthenticated сбой, потому что это еще не установлено в магазине, это в Routes компонент например. Что было бы лучшим способом решить это? Чтобы сложить, я знаю, что я могу использовать условный рендеринг и проверить, когда isAuthenticated определяется, но мне не нравится это решение. Мысли? Спасибо

1 ответ

Решение

Я сделал то, что вы пытаетесь сделать с живым приложением, и использовал в нем Firebase Auth. Вам нужно использовать Действия в качестве входа в систему и только тогда выйти из системы, а затем с помощью componentWillMount() и componentWillReceiveProps() проверить, вошел ли пользователь в систему:

Действия:

import { auth } from '../fire';
export const GET_USER = 'get_user';

export function getUser(){
    return dispatch => {
        auth.onAuthStateChanged(user=>{
            dispatch({
                type: GET_USER,
                payload: user
            });
        });
    };
}

export function login(email,password){
    return dispatch => auth.signInWithEmailAndPassword(email, password);
}

export function logout(){
    return dispatch => auth.signOut();
}

export function createAccount(email, password){
    return dispatch => auth.createUserWithEmailAndPassword(email, password);
}

ваш редуктор должен иметь это:

import {GET_USER} from '../Actions/UserActions';

export default function( state = {loading:true}, action){
    switch (action.type){
        case GET_USER:
            return { loading: false, ...action.payload };
        default:
        return state;
    }
}

в вашем App.js, например, просто в начале этого используйте это:

 componentWillMount(){
   this.props.getUser();
   if(this.props.user.loading === false && this.props.user.email === undefined){
     this.props.history.replace('/Login');
   }
 }

 componentWillReceiveProps(nextProps){
  if(nextProps.user.loading === false && nextProps.user.email === undefined){
    this.props.history.replace('/Login');
  }
 }

это потому, что у вас уже есть учетные данные Auth в ваших реквизитах.

Я надеюсь, что это работает для вас..

Другие вопросы по тегам