I am trying to build a learning app where the user will learn a skill and then give a certain test about it. The problem I am having is that once the user has passed the test, I want the app to always show the passing screen. Meaning, i don't want the app to show the test screen all over everytime the user open the app rather once a test has been passed, the app should permanently store the passing state there. I have no idea how to do it! It would be great if someone helps!
Here's code snippets:
export default test =({navigation}) => {
const [index, setind] = useState(0);
const [idis, setidis] = useState(false);
const [count, setcount] = useState(0);
const [error, setError] = useState('');
const [results, setResults] = useState('');
const [disb, setdis] = useState(true);
const [ndisb, setndis] = useState(true);
useEffect(() => {
//Setting callbacks for the process status
Voice.onSpeechStart = onSpeechStart;
Voice.onSpeechEnd = onSpeechEnd;
Voice.onSpeechResults = onSpeechResults;
Voice.onSpeechError = onSpeechError;
return () => {
//destroy the process after switching the screen
Voice.destroy().then(Voice.removeAllListeners);
};
}, []);
check function for test
function Check() {
if (results.includes(words[index])){
// console.log(index);
Alert.alert('Correct!','You are learning so well!');
if(index==7) {
if(count<5)
{
// Alert.alert('pass','pass');
// showing passing screen in the form of a modal
setshowpass(true);
}
else{
Alert.alert('fail','fail');
}
}
if (index==7){
setndis(true);
setdis(true);
setidis(true);
}
else{
setndis(false);
setdis(true);
setidis(true);
}
}
else{
Alert.alert('Ops!','Looks like you went wrong somewhere. Try again!');
setcount(count 1);
console.log('uc',count);
setdis(true);
setndis(true);
if(count==5){
Alert.alert('Restest', 'Looks like you had way too many mistakes!')
setind(0);
setcount(0);
setdis(true);
}
}
}
const words=['word1', 'wor2', 'word3', 'word4', 'wrd5', 'word6', 'wor7', 'w8'];
const [showpass, setshowpass]=useState(false);
return (
<View style={styles.body}
>
<Modal
transparent={false}
visible={showpass}
animationType='slide'
hardwareAccelerated
>
<View style={styles.body}>
<Text style={styles.toptext}>Congratulations!</Text>
<Text style={styles.toptext}>Worked great in Turkishya!</Text>
<Text style={styles.topptext}>
And mastered the skill 'Alphabets'
</Text>
</View>
</Modal>
<View>
);
}
signup.js:
import React, {useState} from "react";
import {View, StyleSheet, Text, Keyboard, ToastAndroid, LogBox} from 'react-native';
import { TextInput, TouchableOpacity } from "react-native-gesture-handler";
import {Auth} from '../services';
export default signup =({navigation}) => {
const [userName, setName]= useState()
const [email,setEmail]= useState()
const [pass, setpass]=useState()
return (
<View style={styles.body}>
<Text style={styles.toptext}>
Sign Up
</Text>
<View style={styles.inputview}>
<TextInput
style={styles.inputext}
placeholderTextColor='#ffffff88'
placeholder="Enter Your Name"
keyboardType='default'
value={userName}
onChangeText ={e => setName(e)}
/>
</View>
<View style={styles.inputview}>
<TextInput
style={styles.inputext}
placeholderTextColor='#ffffff88'
placeholder="Enter Email"
keyboardType="email-address"
value={email}
onChangeText ={e => setEmail(e)}
/>
</View>
<View style={styles.inputview}>
<TextInput
style={styles.inputext}
placeholderTextColor='#ffffff88'
placeholder="Enter Password"
secureTextEntry
value={pass}
onChangeText ={e => setpass(e)}
/>
</View>
<TouchableOpacity
onPress={() => {Auth.signUp(userName, email,pass); LogBox.ignoreLogs(['Given String is empty or null']); ToastAndroid.showWithGravity('Loading...', ToastAndroid.CENTER, ToastAndroid.CENTER); Keyboard.dismiss();}}
style={styles.button}
>
<Text style={styles.buttontext}>
Sign Up
</Text>
</TouchableOpacity>
<View
style={{
borderBottomColor: '#ffffff99',
borderBottomWidth: 1,
marginLeft:25,
marginRight:25,
marginTop:25,
}}
/>
<View style={{flexDirection: 'row', justifyContent: 'center', alignItems: 'center' }}>
<Text style={styles.lowertext}>
Already have an account?
</Text>
<TouchableOpacity
onPress={() => navigation.navigate('login')}
>
<Text style={styles.nestedtext}>Login Here</Text>
</TouchableOpacity>
</View>
</View>
)
}
auth.js:
import { Alert } from 'react-native';
import auth from '@react-native-firebase/auth';
import firestore from '@react-native-firebase/firestore';
const createUserInDb=(uid, fullName, email)=>{
return firestore().collection('user').doc(uid).set(
{uid,
fullName,
email
}
)
}
const signUp = (fullName, email, password) => {
if(!fullName || !email || !password){
Alert.alert('Error', 'Please enter all fields!')
}
return auth().createUserWithEmailAndPassword(email,password)
.then (cred => {
const {uid} =cred.user;
auth().currentUser.updateProfile({
displayName: fullName
})
return uid
})
.then(
uid => createUserInDb(uid, fullName, email)
)
.catch(
err => Alert.alert (err.code,err.message)
)
}
const signIn = (email, password) => {
if (!email || !password){
Alert.alert('Error', 'Please enter all fields')
}
return auth().signInWithEmailAndPassword(email, password)
.then(()=> {})
.catch(
err => Alert.alert(err.code,err.message)
)
}
const forgetPassword =(email) => {
if(!email){
Alert.alert('Error', 'Please enter Email!')
}
return auth().sendPasswordResetEmail(email)
.then(()=> {
return Alert.alert('Link Sent on Given Email!', 'Check your Email. A password reset link has been sent.')
})
.catch(
err => Alert.alert(err.code,err.message)
)
}
const signOut = () => {
return auth().signOut()
}
const Auth = {
signUp,
signIn,
forgetPassword,
signOut
}
export default Auth
CodePudding user response:
Things like this should usually be handled on the server. However, you could make this persistent on the phone using the AsyncStorage.
Storage functionality
import AsyncStorage from '@react-native-async-storage/async-storage';
// or whatever
const key = "hasPassed"
export const hasPassed = async () => {
return AsyncStorage.getItem(key).then(result => result != null ? JSON.parse(result) : undefined).catch(e => console.log(e))
}
export const setHasPassed = async (newPassed) => {
return AsyncStorage.setItem(key, JSON.stringify({hasPassed: newPassed})).catch(e => console.log(e))
}
Then, use it in your screens as follows.
// or whatever name it is
const MainScreen = () => {
const [showpass, setshowpass] = useState();
useEffect(() => {
const getState = async () => {
const result = await hasPassed()
setshowpass(result ? result.hasPassed : false)
}
getState()
}, [])
// since it is async
if (showpass === undefined) {
return null
}
return (
<View style={styles.body}>
<Modal
transparent={false}
visible={showpass}
animationType='slide'
hardwareAccelerated
>
<View style={styles.body}>
<Text style={styles.toptext}>Congratulations!</Text>
<Text style={styles.toptext}>Worked great in Turkishya!</Text>
<Text style={styles.topptext}>
And mastered the skill 'Alphabets'
</Text>
</View>
</Modal>
<View>
);
}
If you set the state, just save it in the local storage as well as follows.
if(count<5) {
// Alert.alert('pass','pass');
// showing passing screen in the form of a modal
setHasPassed(true).then(() => setshowpass(true))
}