Предполагается ли, что Firebase onAuthStateChange автоматически вызывает перенаправление страницы? - PullRequest
1 голос
/ 09 июня 2019

Мое приложение требует серию отправлений Redux при входе пользователя в систему. Эти отправки должны быть завершены до того, как пользователь будет перенаправлен на страницу в зависимости от состояния магазина. В результате некоторой отладки я обнаружил, что, по-видимому, после входа пользователя в систему и запуска прослушивателя onAuthStateChanged в Firebase страница автоматически перенаправляет пользователя на страницу входа (которая затем перенаправляется с помощью реакции-маршрутизатора, как и должно) когда я объявляю редирект. Есть ли способ предотвратить такое поведение?

Сначала я думал, что переадресация запускается диспетчерами, но после некоторой отладки я сузил поведение до изменения аутентификации. Я могу убедиться, что все работает, как и ожидалось, когда пользователь уже прошел проверку подлинности и обновил страницу.

// A bunch of imports before this

const store = configureStore()

const jsx = (
    <Provider store={store}>
        <AppRouter />
    </Provider>
)

let hasRendered = false

const renderApp = () => {
    if (!hasRendered) {
        store.dispatch(setApi()).then(() => {
            ReactDOM.render(jsx, document.getElementById('app'))
        })
        hasRendered = true
    }
}

ReactDOM.render(<LoadingPage />, document.getElementById('app'))

firebase.auth().onAuthStateChanged(async (user) => {
    if (user) {
        console.log('logged in')
        store.dispatch(login(user.uid))
        await store.dispatch(startGetProfiles(user.uid))

        const profiles = store.getState().profiles
        const selectedCharacterId = localStorage.getItem('selectedCharacterId')
        const profileId = selectedCharacterId || profiles.length === 1 && profiles[0].id

        if (profileId) {
            await store.dispatch(startSetProfile(user.uid, profileId))
        } 
        const profile = store.getState().profile

        renderApp()

        if (!!profile.id) {
            history.push('/profile')
        } else if (profiles.length > 0) {
            history.push('/select')
        } else {
            history.push('/create')
        }
    } else {
        console.log('logged out')
        store.dispatch(logout())
        renderApp()
        history.push('/')
    }
})

Я ожидаю, что перенаправление страницы произойдет только тогда, когда я использую history.push ('/ somepage'), но вместо этого перенаправление запускается сразу после входа пользователя.

1 Ответ

0 голосов
/ 11 июня 2019

Хорошо, вот что я узнал - похоже, что происходит то, что, когда пропадает в моих маршрутах, происходит обновление. Все мои маршруты выглядят примерно так:

export const PrivateRoute = ({
    isAuthenticated,
    component: Component,
    ...rest
}) => (
    <Route {...rest} component={(props) => (
        isAuthenticated ? (
            <Component {...props} />     
        ) : (
            <Redirect to="/" />
        )
    )} />
)

const mapStateToProps = (state) => ({
    isAuthenticated: !!state.auth && !!state.auth.uid
})

export default connect(mapStateToProps)(PrivateRoute)

Обратите внимание, как я использую Redux для проверки подлинности пользователя перед его маршрутизацией. Когда вызовы для отправки действия входа в систему / выхода из системы в моем магазине обновляют значение auth, это обновляет реквизит маршрута isAuthenticated, таким образом вызывая обновление компонента и цепочки маршрутизации. Чтобы решить эту проблему, мне пришлось создать новые маршруты для обработки действий маршрутизатора при обновлении и удалить вызовы history.push() из моего кода onAuthStateChanged.

Итак, чтобы ответить на мой вопрос, Firebase не вызывает перенаправления страниц. При использовании Redux в тандеме с React-Router, будьте осторожны с изменениями в ваших реквизитах маршрута, которые могут вызвать обновление компонентов и повторную маршрутизацию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...