I am checking user is valid or not after displaying splash screen. So In my splash screen I checked the data from redux saga like below
Hide_Splash_Screen=()=>{
this.setState({
isVisible:false
})
if(this.props.phoneNumberData !== null )
{
this.props.navigation.navigate('HomeScreen')
}
else
{
this.props.navigation.navigate('PhoneVerification')
}
}
componentDidMount(){
setTimeout(()=>{
this.Hide_Splash_Screen();
}, 2000);
this.props.fetchSavePhoneNumber()
}
So if the user has install the app for firstime then PhoneVerification Screen is prompted and not it will directly go into HomeScreen
So here is my logic to check phone verification with otp and then store as a new user in saga
handleSendCode=()=>{
var phoneno = '+91'+this.state.phone
firebase
.auth()
.signInWithPhoneNumber(phoneno)
.then(confirmResult => {
this.setState({ confirmResult })
})
.catch(error => {
alert(error.message)
console.log(error)
})
this.setState({showotpScreen:true})
}
checkOtp=()=>{
this.state.confirmResult
.confirm(this.state.otp)
.then(user => {
this.props.NewPhoneNumber(user)
this.props.navigation.navigate('HomeScreen')
})
.catch(error => {
alert(error.message)
console.log(error)
})
}
For ReduxSaga implementation I take two different action and one reducer like this
phoneaction
export const fetchSavePhoneNumber = () => ({
type: 'FETCH_SAVE_PHONENUMBER',
});
export const NewPhoneNumber = (data) => ({
type:'SAVE_NEW_PHONENUMBER',
payload: data
});
phoneReducer
const initialState = {
phoneNumberData: null,
};
export default (state = initialState, { type, payload }) => {
switch(type){
case 'SAVE_NEW_PHONENUMBER':
return{
...state,
phoneNumberData: payload,
};
case 'IS_VALIDATING':
return{
...state,
};
default:
return state;
};
}
And my Two Saga will look like this
NewPhoneNumber
import { call, put, select, takeLatest } from 'redux-saga/effects';
import AsyncStorage from '@react-native-community/async-storage';
const phoneno = state => state.phone.phoneNumberData ;
function* PhoneVerifyTask(action){
const phoneNumberData = yield select(phoneno);
try{
yield call(AsyncStorage.setItem,'phoneVerify',JSON.stringify(phoneNumberData));
yield put({ type: 'SAVE_NEW_PHONENUMBER', payload: phoneNumberData });
}
catch(error){
console.log(error)
}
}
function* NewPhoneNumber(){
yield takeLatest('SAVE_NEW_PHONENUMBER',PhoneVerifyTask)
}
export default NewPhoneNumber;
FetchSavePhoneNumber
import { call, put, takeLatest } from 'redux-saga/effects';
import AsyncStorage from '@react-native-community/async-storage';
function* fetchVerifyPhoneNumber(action){
yield put({
type: 'IS_VALIDATING',
});
try
{
const response = yield call(AsyncStorage.getItem,'phoneVerify')
yield put({
type: 'SAVE_NEW_PHONENUMBER',
payload: JSON.parse(response) || null
});
}
catch(error){
console.log(e);
yield put({
type: 'SAVE_NEW_PHONENUMBER',
payload: {
phoneNumberData: null
},
});
}
}
function* FetchSavePhoneNumber(){
yield takeLatest('FETCH_SAVE_PHONENUMBER',fetchVerifyPhoneNumber)
}
export default FetchSavePhoneNumber;
But after successfully storing newPhoneNumberdata and fetchingExisting PhoneNumberdata my whole redux act as a infinite loop
This is probably because your component that calls FETCH_...
is re-rendered and calls fetch another time.
I'd suggest either calling the action higher up in your app (in your App.js constructor maybe). You can also fire sagas once on app load in your generator directly.