Search code examples
reactjsfirebase-authenticationdialogredux-saga

How do I wait for successful sign in with firebase using a popup dialoug and redux saga


I have a popup dialog where the user can sign in. It works however I want the dialog to wait until the sign in is successful before it closes. I am also using Redux and I tried adding await before emailSignInStart(email, password) but that doesn't work. Here is my Signin Form:

const SigninForm = ({ emailSignInStart, handleClose }) => {
    const { switchToSignup } = useContext(AccountContext);
    const [userCredentials, setCredentials] = useState({
        email: '',
        password: '',
    });
    const { email, password } = userCredentials;

    const signIn = async event => {
        event.preventDefault();
        try {
            emailSignInStart(email, password);
            handleClose(); <---------------------- Don't call this until sign in successful
        } catch(error){
            
        }
    };

    const handleChange = event => {
        const { value, name } = event.target;
        setCredentials({ ...userCredentials, [name]: value });
    };

    return <BoxContainer>
        <Marginer direction={'vertical'} margin={15} />
        <FormContainer>
            <Input name={'email'} type={'email'} onChange={handleChange} placeholder={'Email'} />
            <Input name={'password'} type={'password'} onChange={handleChange} placeholder={'Password'} />
            <Marginer direction={'vertical'} margin={10} />
            <MutedLink href={'#'}>Forgot Password?</MutedLink>
            <Marginer direction={'vertical'} margin={'1.6em'} />
            <Submit type={'submit'} onClick={signIn}>Sign In</Submit>
            <Marginer direction={'vertical'} margin={'1em'} />
            <MutedLink href={'#'}>
                Don't have an account?
                <BoldLink href={'#'} onClick={switchToSignup}>Sign Up</BoldLink>
            </MutedLink>
        </FormContainer>
    </BoxContainer>;
};

const mapDispatchToProps = dispatch => ({
    emailSignInStart: (email, password) =>
        dispatch(emailSignInStart({ email, password })),
});

export default connect(null, mapDispatchToProps)(SigninForm);

In my user sagas I have:

export function* getSnapshotFromUserAuth(userAuth, additionalData) {
    try {
        const userRef = yield call(
            createUserProfileDocument,
            userAuth,
            additionalData
        );
        const userSnapshot = yield userRef.get();
        yield put(
            signInSuccess({ id: userSnapshot.id, ...userSnapshot.data() })
        );
    } catch (error) {
        yield put(signInFailure(error.message));
    }
}

export function* signInWithEmail({ payload: { email, password } }) {
    try {
        const { user } = yield auth.signInWithEmailAndPassword(email, password);
        yield getSnapshotFromUserAuth(user);
        return user;
    } catch (error) {
        yield put(signInFailure(error.message));
    }
}

export function* onEmailSignInStart() {
    yield takeLatest(UserActionTypes.EMAIL_SIGN_IN_START, signInWithEmail);
}

In my user actions I have:

export const emailSignInStart = emailAndPassword => ({
    type: UserActionTypes.EMAIL_SIGN_IN_START,
    payload: emailAndPassword,
});

export const signInSuccess = user => ({
    type: UserActionTypes.SIGN_IN_SUCCESS,
    payload: user,
});

export const signInFailure = error => ({
    type: UserActionTypes.SIGN_IN_FAILURE,
    payload: error,
});

Solution

  • I don't know why but I got this working. All I did is remove the handleClose call after the emailSignInStart(email, password); and it all works. No where does it call the close dialog anymore but it still closes after the sign in is successful.