I'm trying to make an app where I can add item in a flatlist . Then each item I can navigate to a new page only for that specific item . In that page, I can add another flatlist.
To explain it more, lets say I add few Classroom item in the flatlist (Classroom A, Classroom B, Classroom C). When I press Clasroom A , it will navigate to a page named Classroom A . In that page, I can add and delete the name of each students using another flatlist.
How can I design the page for the Classsrooms ??? Because when I add the name of the student in classroom A, the names of the students is also available in the flatlist of other Classrooms.
This is my code for the Main Menu:
import React, { useState , useEffect } from 'react';
import {
View,
Text,
TouchableOpacity,
FlatList,
Alert,
TextInput,
StyleSheet,
} from 'react-native';
import Icon from 'react-native-vector-icons/MaterialIcons';
import AsyncStorage from '#react-native-async-storage/async-storage';
import { useNavigation } from '#react-navigation/native';
export default function MainMenu(){
const [classroomInput, setClassroomInput] = useState('');
const [classroom, setClassroom] = useState([]);
const navigation = useNavigation();
useEffect(() => {
getClassroom();
}, []);
useEffect(() => {
saveClassroom(classroom);
}, [classroom]);
const saveClassroom = async (classroom) => {
try {
const stringifyClassroom = JSON.stringify(classroom);
await AsyncStorage.setItem('classroom', stringifyClassroom);
} catch (error) {
console.log(error);
}
};
const getClassroom = async () => {
try {
const classrooms = await AsyncStorage.getItem('classroom');
if (classrooms !== null) {
setClassroom(JSON.parse(classrooms));
}
} catch (error) {
console.log(error);
}
};
const addClassroom = () => {
if (classroomInput === ''){
Alert.alert('Error', 'Please input class');
} else {
const newClassroom = {
id: Math.random().toString(),
Classroom: classroomInput,
};
setClassroom([...classroom,newClassroom]);
setClassroomInput('');
}
};
const deleteClassroom = (classroomId) => {
const newClassrooms = classroom.filter(item => item.id !== classroomId);
setClassroom(newClassrooms);
};
return (
<View style={styles.container}>
<TextInput
style={styles.input}
placeholder={'Add Classrooms'}
value={classroomInput}
onChangeText={(text) => setClassroomInput(text)}
/>
<TouchableOpacity onPress={() => addClassroom()} style={styles.button}>
<Text>Add Classroom</Text>
</TouchableOpacity>
<FlatList
style={styles.flatlist}
data={classroom}
keyExtractor = { (item) => item.id.toString() }
renderItem={({ item }) => (
<TouchableOpacity onPress= {() => navigation.navigate('Classroom', item)} >
<View style={styles.listItem}>
<View>
<Text style={[styles.classText , {fontSize: 18}]}>
{item?.Classroom}
</Text>
</View>
<View >
<TouchableOpacity style={[styles.delete ]} onPress={() => deleteClassroom(classroom?.id)}>
<Icon name="remove" size={15} color={'#fff'} />
</TouchableOpacity>
</View>
</View>
</TouchableOpacity>
)}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#ecf0f1',
padding: 8,
},
input: {
width: '70%',
borderBottomWidth: 1,
marginBottom: 20,
},
button: {
backgroundColor: 'lightblue',
padding: 10,
marginBottom: 10,
},
delete: {
backgroundColor: '#ff3333',
padding: 5,
color: '#fff',
borderWidth: 1,
borderColor: '#ff9999',
borderRadius: 5,
},
listItem: {
flexDirection: 'row',
justifyContent: 'space-between',
width: '70%',
alignItems: 'center',
},
});
And this is the code for the classroom:
/* eslint-disable prettier/prettier */
import React, { useState , useEffect } from 'react';
import {
View,
Text,
TouchableOpacity,
FlatList,
Alert,
TextInput,
StyleSheet,
} from 'react-native';
import Icon from 'react-native-vector-icons/MaterialIcons';
import AsyncStorage from '#react-native-async-storage/async-storage';
const Classroom = ( {navigation, route}) => {
const [studentInput, setStudentInput] = useState('');
const [student, setStudent] = useState([]);
useEffect(() => {
getStudent();
}, []);
useEffect(() => {
saveStudent(student);
}, [student]);
const saveStudent = async (student) => {
try {
const stringifyStudent = JSON.stringify(student);
await AsyncStorage.setItem('student', stringifyStudent);
} catch (error) {
console.log(error);
}
};
const getStudent = async () => {
try {
const students = await AsyncStorage.getItem('student');
if (students !== null) {
setStudent(JSON.parse(students));
}
} catch (error) {
console.log(error);
}
};
const addStudent = () => {
if (studentInput === ''){
Alert.alert('Error', 'Please input student name');
} else {
const newStudent = {
id: Math.random().toString(),
Name: studentInput,
};
setStudent([...student,newStudent]);
setStudentInput('');
}
};
const deleteStudent = (studentId) => {
const newStudent = student.filter(item => item.id !== studentId);
setStudent(newStudent);
};
return (
<View styles={styles.container}>
<TouchableOpacity onPress={()=> navigation.goBack()} style={styles.button}>
<Text>Back</Text>
</TouchableOpacity>
<Text style={{fontWeight: 'bold', fontSize: 20}}>[ Classroom Name ]</Text>
<TextInput
style={styles.input}
placeholder={'Add Student Name'}
value={studentInput}
onChangeText={(text) => setStudentInput(text)}
/>
<TouchableOpacity onPress={()=> addStudent()} style={styles.button}>
<Text>Add Student</Text>
</TouchableOpacity>
<FlatList
style={styles.flatlist}
data={student}
keyExtractor = { (item) => item.id.toString() }
renderItem={({ item }) => (
<View style={styles.listItem}>
<View>
<Text style={[styles.classText , {fontSize: 18}]}>
{item?.Name}
</Text>
</View>
<View >
<TouchableOpacity style={[styles.delete ]} onPress={() => deleteStudent(item?.id)}>
<Icon name="remove" size={15} color={'#fff'} />
</TouchableOpacity>
</View>
</View>
)}
/>
</View>
);
};
export default Classroom;
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#ecf0f1',
padding: 8,
},
input: {
width: '70%',
borderBottomWidth: 1,
marginBottom: 20,
},
button: {
backgroundColor: 'lightblue',
padding: 10,
marginBottom: 10,
},
listItem: {
flexDirection: 'row',
justifyContent: 'space-between',
width: '70%',
alignItems: 'center',
},
delete: {
backgroundColor: '#ff3333',
padding: 5,
color: '#fff',
borderWidth: 1,
borderColor: '#ff9999',
borderRadius: 5,
},
});
You are using the same AsyncStorage key 'student' regardless of which classroom you are looking at. You need to keep your student lists separate, so you'll need a separate key for each. Something like:
const key = `students_in_room_${classroomId}`
You can get the classroom id (A, B, C) through the route prop from your navigation.
Edit: You would use this unique key instead of the string 'students' for reading and writing to AsyncStorage. That way you can have separate stored values for each classroom.
const students = await AsyncStorage.getItem(key);
await AsyncStorage.setItem(key, stringifyStudent);
Related
Hi I am a new React user and I am trying to add the following component to an app I'm developing:
import React, { useState, useEffect, Component } from 'react';
import { StyleSheet, Text, View, TouchableOpacity } from 'react-native';
import { Camera, CameraType } from 'expo-camera';
function InAppCamera() {
const [hasPermission, setHasPermission] = useState(null);
const [type, setType] = useState(CameraType.back);
useEffect(() => {
(async () => {
const { status } = await Camera.requestCameraPermissionsAsync();
setHasPermission(status === 'granted');
})();
}, []);
if (hasPermission === null) {
return <View />;
}
if (hasPermission === false) {
return <Text>No access to camera</Text>;
}
return (
<View style={styles.container}>
<Camera style={styles.camera} type={type}>
<View style={styles.buttonContainer}>
<TouchableOpacity
style={styles.button}
onPress={() => {
setType(type === CameraType.back ? CameraType.front : CameraType.back);
}}>
<Text style={styles.text}> Flip </Text>
</TouchableOpacity>
</View>
</Camera>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
camera: {
flex: 1,
},
buttonContainer: {
flex: 1,
backgroundColor: 'transparent',
flexDirection: 'row',
margin: 20,
},
button: {
flex: 0.1,
alignSelf: 'flex-end',
alignItems: 'center',
},
text: {
fontSize: 18,
color: 'white',
},
});
export default InAppCamera;
I am trying to reference this component in another .js file as seen below:
<FAB style={styles.fab} small icon="camera" onPress={InAppCamera} />
I get an error for an invalid hook call. Any suggestions would be great thank you so much!
//You can get some idea from the given sample.
const [showCamera, setCamera] = useState(false);
return <View>
/*Other Code If any */
<FAB style={styles.fab} small icon="camera" onPress={() => setCamera(!showCamera)} />
{showCamera ? <InAppCamera /> : null}
/*Other Code If any */
</View>
I am trying to make a Todo/Notes App with Firebase as DB. The app is working perfectly in sync with the FirestoreDB, but every time I close and reopen the app, the app seems to delete the previous credentials and create a new user altogether and all the previous notes are gone from the app, which still exist on the FirestoreDB. Can anyone tell me what am I doing wrong?
This is the App.js
import {
StyleSheet,
Text,
View,
TouchableOpacity,
FlatList,
Modal,
ActivityIndicator,
} from 'react-native';
import colors from './Colors';
import { AntDesign } from '#expo/vector-icons';
import TodoList from './components/TodoList';
import AddListModal from './components/AddListModal';
import Fire from './Fire';
export default class App extends React.Component {
state = {
addTodoVisibile: false,
lists: [],
user: {},
loading: true,
};
componentDidMount() {
firebase = new Fire((error, user) => {
if (error) {
return alert('Something went wrong');
}
firebase.getLists(lists => {
this.setState({ lists, user }, () => {
this.setState({ loading: false });
});
});
this.setState({ user });
});
}
componentWillUnmount() {
firebase.detach();
}
toggleAddTodoModal() {
this.setState({ addTodoVisibile: !this.state.addTodoVisibile });
}
renderList = list => {
return <TodoList list={list} updateList={this.updateList} />;
};
addList = list => {
firebase.addList({
name: list.name,
color: list.color,
todos: [],
});
};
updateList = list => {
firebase.updateList(list);
};
deleteList = list => {
firebase.deleteList(list);
};
renderList = list => {
return (
<TodoList
list={list}
updateList={this.updateList}
deleteList={this.deleteList}
/>
);
};
render() {
if (this.state.loading) {
return (
<View style={styles.container}>
<ActivityIndicator size={50} color={colors.highlight} />
</View>
);
}
return (
<View style={styles.container}>
<Modal
animationType='slide'
visible={this.state.addTodoVisibile}
onRequestClose={() => this.toggleAddTodoModal()}
>
<AddListModal
closeModal={() => this.toggleAddTodoModal()}
addList={this.addList}
/>
</Modal>
<View style={{ flexDirection: 'row' }}>
<View style={styles.divider} />
<Text style={styles.title}>
Post
<Text
style={{
fontWeight: '500',
color: colors.highlight,
}}
>
It
</Text>
</Text>
<View style={styles.divider} />
</View>
<View style={{ marginVertical: 48 }}>
<TouchableOpacity
style={styles.addList}
onPress={() => this.toggleAddTodoModal()}
>
<AntDesign name='plus' size={25} color={colors.white} />
</TouchableOpacity>
<Text style={styles.add}>Add a List</Text>
</View>
<View style={{ height: 275 }}>
<FlatList
data={this.state.lists}
keyExtractor={item => item.id.toString()}
horizontal={true}
showsHorizontalScrollIndicator={false}
renderItem={({ item }) => this.renderList(item)}
keyboardShouldPersistTaps='always'
/>
</View>
<Text style={styles.delete}>
<Text style={styles.highlight}>(</Text>
Long Press on List to Delete
<Text style={styles.highlight}>)</Text>
</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: colors.background,
alignItems: 'center',
justifyContent: 'center',
},
divider: {
backgroundColor: colors.highlight,
height: 1,
flex: 1,
alignSelf: 'center',
},
title: {
fontSize: 38,
fontWeight: '800',
color: colors.white,
paddingHorizontal: 64,
},
addList: {
borderWidth: 2,
borderColor: colors.highlight,
borderRadius: 4,
padding: 16,
alignItems: 'center',
},
add: {
color: colors.white,
fontWeight: '600',
fontSize: 16,
marginTop: 8,
},
delete: {
color: colors.white,
fontWeight: '500',
fontSize: 12.5,
position: 'absolute',
bottom: 8,
},
highlight: {
color: colors.highlight,
},
});
and this is Fire.js
import 'firebase/compat/firestore';
import 'firebase/compat/auth';
const firebaseConfig = {
};
class Fire {
constructor(callback) {
this.init(callback);
}
init(callback) {
if (!firebase.apps.length) {
firebase.initializeApp(firebaseConfig);
}
firebase.auth().onAuthStateChanged(user => {
if (user) {
callback(null, user);
} else {
firebase
.auth()
.signInAnonymously()
.catch(error => {
callback(error);
});
}
});
}
getLists(callback) {
let ref = this.ref.orderBy('name');
this.unsubscribe = ref.onSnapshot(snapshot => {
lists = [];
snapshot.forEach(doc => {
lists.push({ id: doc.id, ...doc.data() });
});
callback(lists);
});
}
addList(list) {
let ref = this.ref;
ref.add(list);
}
updateList(list) {
let ref = this.ref;
ref.doc(list.id).update(list);
}
deleteList(list) {
let ref = this.ref;
ref.doc(list.id).delete();
}
get userId() {
return firebase.auth().currentUser.uid;
}
get ref() {
return firebase
.firestore()
.collection('users')
.doc(this.userId)
.collection('lists');
}
detach() {
this.unsubscribe();
}
}
export default Fire;
On most environments the Firebase Authentication SDK will automatically persist the user credentials and restore them when the app/page is reloaded, and then call your onAuthStateChanged handler.
On React Native this is not possible by default though, so I recommend checking out the Firebase documentation on managing auth persistence..
I'm new to React Native, and I'm following along with an online tutorial.
This is my App.js file:
import React, { useState, useEffect } from 'react';
import {View,Text,ImageBackground,FlatList, Image, TouchableHighlight } from 'react-native';
import bookmarkIcon from './assets/bookmark.png';
import readIcon from './assets/read.png';
import styles from './styles';
const ArticleItem = ({article}) => {
const { title, description, url, urlToImage } = article;
return (
<View style = { styles.articleContainer }>
<Image style={ styles.articleImage } source={{ uri: urlToImage }} />
<Text style= { styles.articleTitle }>
{ title }
</Text>
<Text style = { styles.articleDescription }>
{ description }
</Text>
<View style = { styles.articleBtns}>
<IconButton width= "50%" color = "white" bgcolor = "#ff5c5c" icon = { readIcon } onPress = { () => { console.log("Button pressed!")} } title = "Open" />
<IconButton width= "50%" color = "white" bgcolor = "#ff5c5c" icon = { bookmarkIcon } onPress = { () => { console.log("Button pressed!")} } title = "Read later" />
</View>
</View>
)
}
FlatListItemSeparator = () => {
return (
<View
style={{
height: 1,
width: "100%",
backgroundColor: "#000",
}}
/>
);
}
FlatListHeader = () => {
return (
<View elevation={1}
style={{
height: 100,
width: "97%",
margin: 5,
backgroundColor: "#fff",
border: 2.9,
borderColor: "black",
alignSelf: "center",
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 16,
},
shadowOpacity: 1,
shadowRadius: 7.49
}}
>
<Text style={{
textShadowColor: 'black',
textShadowOffset: { width: 1, height: 3 },
textShadowRadius: 10,
fontSize: 40,
fontWeight: '800',
flex: 1,
alignSelf: "center",
paddingTop: 30
}}
>Latest articles</Text>
</View>
);
}
const IconButton = ({title, color, bgcolor, onPress, width, icon }) =>{
return (
<TouchableHighlight onPress = { onPress } style= { { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', backgroundColor: bgcolor } }>
<View style={ {width: width, flexDirection: 'row', justifyContent: 'center', alignItems: 'center' } }>
<Image style = { { height: 27, width:27, margin : 5 } } source = { icon }></Image>
<Text style = { {color: color }} > { title } </Text>
</View>
</TouchableHighlight>
);
}
const HomeScreen = (props) => {
console.log("articles: ", props.articles);
return (
<View>
<FlatList
data={ props.articles }
ListHeaderComponent = { this.FlatListHeader }
ItemSeparatorComponent = { this.FlatListItemSeparator}
keyExtractor={(item, index) => index.toString()}
renderItem={({item}) => <ArticleItem article = { item } />}
/>
</View>
);
}
const SplashScreen = (props) => {
return (
<View style = { styles.container } >
<ImageBackground style= { styles.backgroundImage } source={{uri: 'http://i.imgur.com/IGlBYaC.jpg'}} >
<View style= { styles.logoContainer }>
<Text style = { styles.logoText }>
Newzzz
</Text>
<Text style = { styles.logoDescription }>
Get your doze of daily news!
</Text>
</View>
</ImageBackground>
</View>
);
}
const App = () => {
const URL = 'https://raw.githubusercontent.com/nimramubashir/React-Native/fetch/articles.json';
const [articles, setArticles] = useState([]);
const [loading, setLoading ] = useState(true);
useEffect(()=>{
fetch(URL)
.then((response) => response.json())
.then((responseJson) => {
return responseJson.articles;
})
.then( articles => {
setArticles(articles);
console.log(articles);
setLoading(false);
})
.catch( error => {
console.error(error);
});
} , []);
if (loading){
return <SplashScreen />
} else {
return <HomeScreen articles = { articles }/>
}
};
export default App
The code is the same as the tutorial, but when I'm trying to run this code, I'm getting an Error
ReferenceError: FlatListItemSeparator is not defined
I've tried to import the FlatListItemSeparator, but since it is read-only, I can't. I'm getting this error at both FlatListItemSeparator and FlatListHeader. Why am I getting this error, and how can I solve it?
you are having each component as separate Function-Component. The tutorial is probably based on Class-Components. In Function-Components there is no this, so just remove the this.
I want to navigate from my login screen to the home screen without showing the view. I am trying to do is if from the splash screen if it gets the username from async storage then move to login page ...wherein login page by if the username matches from the POST method in login screen directly login if not then show the login screen view
here is my code
import React ,{useState} from 'react';
import {
View,
Text,
TouchableOpacity,
TextInput,
Platform,
StyleSheet ,
StatusBar,
Alert
} from 'react-native';
import * as Animatable from 'react-native-animatable';
import LinearGradient from 'react-native-linear-gradient';
import FontAwesome from 'react-native-vector-icons/FontAwesome';
import Feather from 'react-native-vector-icons/Feather';
import { useTheme } from 'react-native-paper';
const asdf = ({navigation}) => {
const STORAGE_KEY = 'username';
const [userName, setUserName ] = useState('');
const [errortext, setErrortext] = useState('');
const retrieveData = async () => {
try {
const value = await AsyncStorage.getItem(STORAGE_KEY);
if (value !== null) {
var str = value;
// str = str.replace(/^"|"$/g, '');
str = str.replace(/"/g,'');
fetchData(str);
}
} catch (error) {
// Error retrieving data
}
};
retrieveData();
const handleSubmitPress = () => {
if (!userName){
setUserName('')
// onChangeText();
return
} else{
fetchData(userName);
}
setUserName('')
//onChangeText();
}
const fetchData = (userName) => {
if(userName){
let dataToSend = {search :userName}
let formBody = [];
for (let search in dataToSend) {
let encodeKey = encodeURIComponent(search);
let encodeValue = encodeURIComponent(dataToSend[search]);
formBody.push(encodeKey + '=' + encodeValue);
}
formBody = formBody.join('&');
fetch('https://qwert/work/rest/apiofficeapp.php', {
method: 'POST', //Request Type
body: formBody, //post body
headers: {
//Header Defination
'Content-Type':
'application/x-www-form-urlencoded;charset=UTF-8',
},
})
.then((response) => response.json())
.then((responseJson) => {
if (responseJson[0] != ''){
//alert(JSON.stringify(responseJson[0]));
const saveData = async () => {
try {
await AsyncStorage.setItem(STORAGE_KEY, responseJson[0][0]['username'])
//await AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(responseJson[0][0]['username']))
//alert('Data successfully saved login page')
} catch (e) {
//alert('Failed to save the data to the storage')
}
}
saveData();
navigation.navigate('HomeApp');
setErrortext('');
}else {
setErrortext(userName + 'user not found')
}
})
.catch((error) => {
console.error(error);
});
} }
// const onChangeText = userName => setUserName(userName)
const onChangeText = userName => setUserName(userName)
const { colors } = useTheme();
// const onChangeText = (val) => {
// if( val.length !== 0 ) {
// setUserName({
// ...userName,
// userName: val,
// });
// } else {
// setUserName({
// ...userName,
// userName: val,
// });
// }
// }
return (
<View style={styles.container}>
<StatusBar backgroundColor='#009387' barStyle="light-content"/>
<View style={styles.header}>
<Text style={styles.text_header}>Welcome!</Text>
</View>
<Animatable.View
animation="fadeInUpBig"
style={[styles.footer, {
backgroundColor: colors.background
}]}
>
<Text style={[styles.text_footer, {
color: colors.text
}]}>Username</Text>
<View style={styles.action}>
<FontAwesome
name="user-o"
color={colors.text}
size={20}
/>
<TextInput
placeholder="Your Username"
placeholderTextColor="#666666"
style={[styles.textInput, {
color: colors.text
}]}
autoCapitalize="none"
onChangeText={(userName) => onChangeText(userName)}
onSubmitEditing={handleSubmitPress}
/>
</View>
{/* {data.check_textInputChange ?
<Animatable.View
animation="bounceIn"
>
<Feather
name="check-circle"
color="red"
size={20}
/>
</Animatable.View>
: null}
</View> */}
<View>
{errortext != '' ? (
<Text style={styles.errorMsg}>
{errortext}
</Text>
) : null}
</View>
<View style={styles.button}>
<TouchableOpacity
style={styles.signIn}
onPress={() => {handleSubmitPress()}}
>
<LinearGradient
colors={['#eb0c00', '#A80900']}
style={styles.signIn}
>
<Text style={[styles.textSign, {
color:'#fff'
}]}> Sign In </Text>
</LinearGradient>
</TouchableOpacity>
<TouchableOpacity
onPress={() => navigation.navigate('Register')}
style={[styles.signIn, {
borderColor: '#A80900',
borderWidth: 1,
marginTop: 15
}]}
>
<Text style={[styles.textSign, {
color: '#A80900'
}]}> Register </Text>
</TouchableOpacity>
</View>
</Animatable.View>
</View>
);
};
export default asdf;
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#A80900'
},
header: {
flex: 1,
justifyContent: 'flex-end',
paddingHorizontal: 20,
paddingBottom: 50
},
footer: {
flex: 3,
backgroundColor: '#fff',
borderTopLeftRadius: 30,
borderTopRightRadius: 30,
paddingHorizontal: 20,
paddingVertical: 30
},
text_header: {
color: '#fff',
fontWeight: 'bold',
fontSize: 30
},
text_footer: {
color: '#05375a',
fontSize: 18
},
action: {
flexDirection: 'row',
marginTop: 10,
borderBottomWidth: 1,
borderBottomColor: '#f2f2f2',
paddingBottom: 5
},
actionError: {
flexDirection: 'row',
marginTop: 10,
borderBottomWidth: 1,
borderBottomColor: '#FF0000',
paddingBottom: 5
},
textInput: {
flex: 1,
marginTop: Platform.OS === 'ios' ? 0 : -12,
paddingLeft: 10,
color: '#05375a',
},
errorMsg: {
color: '#FF0000',
fontSize: 14,
},
button: {
alignItems: 'center',
marginTop: 50
},
signIn: {
width: '100%',
height: 50,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 10
},
textSign: {
fontSize: 18,
fontWeight: 'bold'
}
});
I not able to navigate to home app without showing the login screen directly
One thing you can try is to use a Splash lib that will create an actual native screen for the splash and you just dismiss the splash screen on the login screen or the main screen.
One lib you may use:
https://github.com/crazycodeboy/react-native-splash-screen
It fairly simple to install and you just need to call this on your Login or Mais screen when its mounted:
import SplashScreen from 'react-native-splash-screen'
export default class MainPage extends Component {
componentDidMount() {
SplashScreen.hide();
}
}
Success on your project.
//this is my accounts.js where i am fetching accounts from user node in user node and pass to the card.js component where every account prints in cards with accounttitle and accountbalance . but when i take snapshot of one user's accounts they are fetched in ascending order but i want to get accounts from firebase in descending order how can i do this.this is my database structure in firebase
import React, { useState, useEffect } from "react";
import { Fontisto } from "#expo/vector-icons";
import Firebase from "../components/Firebase";
import { StyleSheet, Text, View, TouchableOpacity } from "react-native";
import Cards from "../components/Accounts/Cards";
import AddAccountModal from "../components/Accounts/AddAccountModal";
import FundTransferModal from "../components/Accounts/FundTransferModal";
export default function AccountsScreen() {
let add = {
id: 111,
title: "Add",
backgroundColor: "#fff",
};
let [total, setTotal] = useState(0);
let [accounts, setAccount] = useState([]);
const [backgroundColor, setbackgroundColor] = useState("#ff7f50");
const [addAccountmodal, SetAddAccountmodal] = useState(false);
const [fundModal, setFundModal] = useState(false);
const showAddmodal = () => {
SetAddAccountmodal(true);
};
const closeAddmodal = () => {
setbackgroundColor("#ff7f50");
SetAddAccountmodal(false);
};
const showFundModal = () => {
setFundModal(true);
};
const closeFundModal = () => {
setFundModal(false);
};
useEffect(() => {
let user = Firebase.auth().currentUser;
let uid = user.uid;
Firebase.database()
.ref("users/" + uid)
.child("accounts")
.on("value", (snapshot) => {
let tempAccounts = [];
let temptotal = 0;
snapshot.forEach(function (snapshotAccount) {
let account = {
id: snapshotAccount.key,
title: snapshotAccount.val().title,
balance: snapshotAccount.val().balance,
backgroundColor: snapshotAccount.val().backgroundColor,
};
let balance = parseFloat(account.balance, 10);
temptotal = temptotal + balance;
tempAccounts.push(account);
});
tempAccounts.push(add);
setTotal(temptotal);
setAccount(tempAccounts);
});
}, []);
return (
<View style={styles.container}>
<AddAccountModal
addAccountmodal={addAccountmodal}
closeAddmodal={closeAddmodal}
backgroundColor={backgroundColor}
setbackgroundColor={setbackgroundColor}
/>
<FundTransferModal
fundModal={fundModal}
closeFundModal={closeFundModal}
/>
<View style={styles.headingContent}>
<Text style={styles.heading}>Accounts</Text>
<View style={styles.balanceContent}>
<Text style={styles.heading}>Total: </Text>
<Text style={styles.balance}>+ Rs.{total}</Text>
<View style={styles.icon}>
{/* <TouchableOpacity onPress={() => showFundModal()}>
<Fontisto name="arrow-swap" size={25} color="#29416F" />
</TouchableOpacity> */}
</View>
</View>
</View>
<Cards accounts={accounts} showAddmodal={showAddmodal} />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
},
headingContent: {
marginTop: 10,
paddingTop: 10,
paddingHorizontal: 21,
width: "100%",
height: 50,
flexDirection: "row",
justifyContent: "space-between",
},
balanceContent: {
flexDirection: "row",
},
heading: {
color: "#333",
fontWeight: "bold",
fontSize: 16,
},
balance: {
color: "green",
fontWeight: "bold",
fontSize: 16,
},
icon: {
flexDirection: "row",
justifyContent: "flex-end",
marginLeft: "5%",
justifyContent: "center",
},
});
We can use orderBy event to get data in asc or desc order.
For Example: citiesRef.orderBy("name", "desc"),
Reference: https://firebase.google.com/docs/firestore/query-data/order-limit-data