How to use redux on a global functions - react-native

Iam currently working with a react-native project and wanted to use redux now what i want is that a global function that handles all firebase fetch data here is my globla function
connectFunctions.js
export const pullDataFromFirebaseSubCollection = async (collectionName, docId, subCollection, reducerName,) => {
const q = query(collection(db, collectionName,docId,subCollection));
const querySnapshot = await getDocs(q);
const documents = querySnapshot.docs.map((doc) => ({ key_id: doc.id, ...doc.data() }));
var redData = {
reducerName:reducerName,
data:documents
}
store.dispatch(middlewareDispatch(redData))//tried it inside the function does not work
return documents;
}
so on my App.js i imported then connectFunction.js and use pullDataFromFirebaseSubCollection
useEffect(()=>{
let isMounted = true; // note mutable flag
onAuthStateChanged(auth, (user) => {
if (user) {
console.log("user appjs", user);
dispatch(updateLoginStatus(true));
pullDataFromFirebaseSubCollection("Students","1","playlist","playlist").then((data)=>{
}).catch((err)=>{
console.log("logged error", err);
})
} else {
dispatch(updateLoginStatus(false))
}
_handleFinishLoading()
})
return () => { isMounted = false }
},[])
so on my library.js
i called store.getState().reducer.playlist the result is empty

Related

Expo apple sign in doesnt work in production

Trying to implement apple sign in in my expo managed project and the sign in doesnt work in production. I have followed all the documentations steps. Changed the bundle ID to the right one.
const handleAppleRegister = (dispatch) => async () => {
try {
// await firebase.auth().signOut() // sign out first
const nonce = Math.random().toString(36).substring(2, 10);
return await Crypto.digestStringAsync(Crypto.CryptoDigestAlgorithm.SHA256, nonce)
.then((hashedNonce) =>
AppleAuthentication.signInAsync({
requestedScopes: [AppleAuthentication.AppleAuthenticationScope.FULL_NAME, AppleAuthentication.AppleAuthenticationScope.EMAIL],
nonce: hashedNonce
})
)
.then((appleCredential) => {
const { identityToken } = appleCredential;
const provider = new firebase.auth.OAuthProvider('apple.com');
provider.addScope('email');
provider.addScope('name');
provider.addScope('displayName');
provider.addScope('photoURL');
const credential = provider.credential({
idToken: identityToken,
rawNonce: nonce
});
return Firebase.auth().signInWithCredential(credential).then(async resp => {
console.log(resp)
const currentUserUID = resp.user.uid;
const db = firebase.firestore();
db.collection('users').doc(currentUserUID).set({
email: resp.additionalUserInfo.profile.email,
uid: resp.user.uid,
});
await AsyncStorage.setItem('status', 'apple');
dispatch({ type: 'handleAppleRegister', payload: 'apple' });
});
})
.catch((error) => {
// ...
console.error(error);
});
} catch (e) {
if (e.code === 'ERR_CANCELED') {
// handle that the user canceled the sign-in flow
} else {
// handle other errors
}
}
};
I've searched every where for a solution but with no luck. Anyone knows what is missing here

React Redux rejectWithValue() not working

I'm currently facing a problem, when I try to reject a value when my node-fetch request fail, thunkApi.rejectWithValue() isn't working. However when my request is pending or when It's fulfilled, It's working fine.
Here's my slice :
export const userSlice = createSlice({
name: "user",
initialState: initialState as User,
reducers: {
...
},
extraReducers: (builder) => {
...
builder.addCase(changePassUser.pending, (state) => {
GGLog("FETCHING CHANGEPASS API...");
state.isFetching = true;
return state;
});
builder.addCase(changePassUser.fulfilled, (state, { payload }) => {
GGLog("FULFILLED CHANGEPASS:", JSON.stringify(payload));
state.isFetching = false;
state.isSuccess = true;
state.isError = false;
return state;
});
// eslint-disable-next-line #typescript-eslint/no-explicit-any
builder.addCase(changePassUser.rejected, (state, { payload }: any) => {
GGLog("REJECTED CHANGEPASS:", JSON.parse(payload));
state.isFetching = false;
state.isError = true;
state.errorMessage = payload.data;
return state;
});
},
});
Here's my thunk :
export const changePassUser = createAsyncThunk(
"users/password/update",
async ({ oldpassword, newpassword }: RegisterParameters, thunkAPI) => {
try {
const res = await changePassApi.changePass.return({
oldpassword: oldpassword,
newpassword: newpassword,
});
GGLog("API_CHANGEPASS_RES:", res);
const data = await res.json();
if (res.ok) {
GGLog("API_DATA_RESPONSE_OK: ", data);
const tokenData = JSON.stringify(res.headers);
const token = JSON.parse(tokenData).map["x-auth"];
await localStorage.store("token", token);
return data;
} else {
GGLog("API_DATA_RESPONSE_NOK: ", data);
return thunkAPI.rejectWithValue(data);
}
} catch (e) {
GGLog("Error while fetching Login API => ", e);
return thunkAPI.rejectWithValue(e);
}
}
);
And here's the result in the console :
Console output
Any ideas ? Am I missing something ?
Thanks :)
Okay I've found my problem, I was just focused on the thunk and didn't pay attention to the promise rejection. I was trying to parse a JSON that does'nt exist... Just remove the GGLog("REJECTED CHANGEPASS:", JSON.parse(payload));in the slice.
It's working fine now !

React Native UseEffect function is not working according to order

I want to get user's current location and set it into AsyncStorage a array. I will do it in the useEffect hook. But the problem is my functions are not working that according to given order. Here are my code
useEffect(() => {
getUserLocation();
setUserLocation();
check();
}, []);
/*Get User's Currunt Location*/
const getUserLocation = () => {
GetLocation.getCurrentPosition({
enableHighAccuracy: true,
timeout: 15000,
})
.then((location) => {
var lt = location.latitude;
var lg = location.longitude;
setlatitude(lt);
setlongitude(lg);
console.log("getUserLocation", lt, lg);
})
.catch((error) => {
const { code, message } = error;
console.warn(code, message);
});
};
/*Set User's Currunt Location to AsyncStorage*/
const setUserLocation = async () => {
try {
await AsyncStorage.setItem("user_location", JSON.stringify(userLocation));
console.log("setUserLocation", userLocation);
} catch (error) {
console.log("error setting user location");
}
};
const check = () => {
AsyncStorage.getItem("user_location", (err, result) => {
if (result !== null) {
console.log("check", result);
setlatitude(result.latitude);
setlongitude(result.longitude);
} else {
console.log("Data Not Found");
}
});
};
Whenever you use .then you are scheduling your code to run at some point in the future, when the promise has completed. So setUserLocation runs before the then of getUserLocation.
Also, it looks like your getUserLocation set react state, which won't be available until the next render. We use effects to manage this.
// Get the location on mount
useEffect(getUserLocation, []);
// Whenever the location updates, set it into storage
useEffect(() => setUserLocation().then(check), [latitude, longitude]);

React Hook: Pass one value from custom react hook to another react custom hook?

I am trying to figure out how custom hooks are working. I want to get the person ID from one custom hook and pass the ID to a custom hook to get the user details. Is this working?
The user detail hook is always executed first and because of this it is not working.
App.js
const username = props.navigation.getParam('username');
const id = usePersonId('username');
const userInfo = useUserInfo(id);
usePersonId
export default (username) => {
const [personId, setPersonId] = useState(0);
useEffect(async () => {
let token = await new keys().getToken();
let x = await new userService().getPersonId(token, username);
setPersonId(x.user_id);
return () => {
console.log("cleaned up");
};
}, [])
return personId;
}
useUserInfo
export default (id) => {
const [userInfo, setUserInfo] = useState('');
useEffect(async () => {
let token = await new keys().getToken();
let x = await new userDetails().getUserInfo(token, id);
const info = {
"picture": pictureUrl,
};
setUserInfo(info);
return () => {
console.log("cleaned up");
};
}, [])
return userInfo;
Thanks,
Jan

AsyncStorage not getting into then() method in react native

It seems like the async await doesn't work in react native. When I run the code below, it just logs 'here", not the value.
class CompanyDetails extends Component {
...
componentDidMount = async () => {
await this.getCompDetailsData();
}
getCompDetailsData = async () => {
console.log('here');
await AsyncStorage.getItem('CompanyID')
.then((value) => {
console.log(value);
const compID = JSON.parse(value);
console.log(compID);
this.props.getCompDetails(propID);
});
};
...
Does anyone know why it is happening?
Thanks
Did you had 'CompanyID' stored somewhere before because if you did not store it before then it will go to the catch part which is not implemented in your case
getCompDetailsData = async () => {
console.log('here');
await AsyncStorage.getItem('CompanyID')
.then((value) => {
console.log(value);
const compID = JSON.parse(value);
console.log(compID);
this.props.getCompDetails(propID);
}).catch(error => {
console.log("CompanyID is not defined yet");
});
};
You may not have a saved value in that name "CompanyID"