React Native Keyboard Aware Scroll View Squeezing Content - css

I was recently working on a React Native project and I choose to use KeyBoardAwareScrollView to handle the keyboard scroll of the screen. The Below image shows the design which should be actual but when I use keyboardAvoidingView it starts to add padding to the bottom of the screen while I want the screen to scroll up when the keyboard is visible, after doing some research I came across the KeyboardAvoidingScrollView but using that if i give they height of
flex: 1
If i change this line to a static height it fixes the issue on a static screen
scrollContainer: { height: 1000 }
to the container that holds the content everything is pushed to the top.
To somehow adjust the view I gave the scroll container fixed height that did solve the problem temporarily but didn't work on all screen sizes.
My Code Looks like this
import {
View,
Text,
StyleSheet,
SafeAreaView,
Image,
StatusBar,
KeyboardAvoidingView,
} from "react-native";
import AuthContent from "../../auth/AuthContent";
import AuthForm from "../../auth/AuthForm";
import CustomTextInput from "../../components/CustomTextInput";
import { setEmailPass } from "../../../redux/UserReucer";
import { useDispatch } from "react-redux";
import { useSelector } from "react-redux";
import { ImageBackground } from "react-native";
import { GlobalStyles } from "../../../consts/GlobalConsts";
import OrientationLoadingOverlay from "react-native-orientation-loading-overlay";
import { useState } from "react";
import Loading from "../../components/Loading";
import { getAxiosClient } from "../../apis/TallyApi";
import { showAlert } from "../../../utils/Alert";
import { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view";
const SignUpScreen = ({ navigation }) => {
const dispatch = useDispatch();
const currentUser = useSelector((state) => {
return state.mUser;
});
const [isLoading, setIsLoading] = useState(false);
// console.log("Redux state", currentUser);
async function loginHandler({ email, password }) {
setIsLoading(true);
console.log("Signup Screen", email, password);
try {
let response = await getAxiosClient().post("/users/checkEmail", {
email: email,
});
dispatch(setEmailPass({ email, password }));
navigation.navigate("RoleScreen");
console.log("Axios response ", response.data);
} catch (err) {
// const { response } = err;
// const { request, ...errorObject } = response;
console.log("Axios Error ", err.response.data.message);
showAlert(err.response.data.message);
// console.error(err);
// console.error(err);
} finally {
setIsLoading(false);
}
}
return (
<>
<ImageBackground
source={require("../../../../assets/background_color.png")}
style={GlobalStyles.backgroundContainer}
>
<SafeAreaView style={styles.container}>
<KeyboardAwareScrollView
style={styles.container}
behavior={Platform.OS === "ios" ? "padding" : "height"}
>
<View style={styles.scrollContainer}>
<StatusBar barStyle="light-content" />
<View style={styles.topSpace}></View>
<View style={styles.mainContainer}>
<View style={styles.imageContainer}>
<Image
style={styles.image}
source={require("../../../../assets/email_icn.png")}
></Image>
</View>
<View style={styles.textContainer}>
<Text style={styles.largeText}>Continue with email</Text>
<Text style={styles.smallText}>
Enter your email address to get register with palace
</Text>
</View>
<View style={styles.authContainer}>
<AuthContent
styles={styles.authContainer}
onAuthenticate={loginHandler}
></AuthContent>
</View>
</View>
<View style={styles.bottomSpace}></View>
<Loading isLoading={isLoading}></Loading>
</View>
</KeyboardAwareScrollView>
</SafeAreaView>
</ImageBackground>
</>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
},
scrollContainer: { flex: 1 },
largeText: {
fontSize: 30,
color: "white",
marginVertical: 9,
textAlign: "center",
},
smallText: {
fontSize: 16,
color: "white",
marginVertical: 9,
textAlign: "center",
},
topSpace: {
flex: 0.5,
},
mainContainer: {
flex: 8.5,
},
bottomSpace: {
flex: 1,
},
imageContainer: {
flex: 3,
alignItems: "center",
justifyContent: "center",
},
textContainer: {
flex: 1.5,
justifyContent: "center",
},
authContainer: {
flex: 2.5,
},
image: {
resizeMode: "contain",
height: "90%",
},
});
export default SignUpScreen;

Just use a <ScrollView> rather than <KeyboardAwareScrollView>

Related

postion view first on screen and after scroll view react native

I am trying to make a custom header in react native tsx and for that I made a function renderHeader that I call before scroll view because I don't want it to be scrollable ...
but it does not work
Please help me
and the code :
import { ScrollView, StyleSheet, Text, View, StatusBar } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
export default function App() {
const heightBar=StatusBar.currentHeight;
const renderHeader = () => {
return (
<View style={styles.headerContainer}>
<Text>hey</Text>
</View>
);
};
return (
<SafeAreaView style={styles.container}>
{renderHeader()}
<ScrollView style={styles.ScrollView}>
<Text>buna</Text>
</ScrollView>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
headerContainer: {
position: 'absolute',
flex:1,
paddingTop: StatusBar.currentHeight,
backgroundColor: 'pink',
height: 10,
borderBottomColor: 'black',
},
container: {
flex: 1,
backgroundColor: 'white',
},
ScrollView: {
flex: 1,
marginHorizontal: 20,
},
});
Thanks in Advance !
enter image description here
header is way up than statusbar.currentHeight
Your problem is in layout:
headerContainer: {
position: 'absolute',
flex:1,
paddingTop: StatusBar.currentHeight,
backgroundColor: 'pink',
height: 10,
borderBottomColor: 'black',
},
There is no need to pisition header "absolute". Remove it, or set it to relative.
Also don't set height and flex at the same time. It looks like you don't understand what flex does. If it is so, please do your research, it is very important.
minimal example what i think you want to achieve:
import { ScrollView, StyleSheet, Text, View, StatusBar, SafeAreaView } from 'react-native';
export default function App() {
const renderHeader = () => {
return (
<View style={styles.headerContainer}>
<Text>hey</Text>
</View>
);
};
return (
<SafeAreaView style={styles.container}>
{renderHeader()}
<ScrollView style={styles.ScrollView}>
<Text>buna</Text>
</ScrollView>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
headerContainer: {
backgroundColor: 'pink',
borderBottomColor: 'black',
},
container: {
flex: 1,
backgroundColor: 'blue',
},
ScrollView: {
flex: 1,
marginHorizontal: 20,
},
});

TypeError: undefined is not an object on react native app

the code below of my react native app needs to display a simple background image to do that I use in below code (I use css and js), when I run the code I get the following error, it tells me the width parameter is not defined though it is how do I solve this?
Error Width React Native:
:19 in handleException
at node_modules/react-native/Libraries/Core/ReactFiberErrorDialog.js:43:2 in showErrorDialog
at node_modules/react-native/Libraries/ReactNative/renderApplication.js:54:4 in renderApplication
at node_modules/react-native/Libraries/ReactNative/AppRegistry.js:117:25 in runnables.appKey.run
at node_modules/react-native/Libraries/ReactNative/AppRegistry.js:213:4 in runApplication
TypeError: undefined is not an object (evaluating 'style.width')
This error is located at:
TypeError: undefined is not an object (evaluating 'style.width')
This error is located at:
in NavigationContainer (at Router.js:101)
in App (at Router.js:127)
in Router (at App.js:8)
in App (created by ExpoRoot)
in ExpoRoot (at renderApplication.js:45)
in RCTView (at View.js:34)
in View (at AppContainer.js:106)
in DevAppContainer (at AppContainer.js:121)
in RCTView (at View.js:34)
in View (at AppContainer.js:132)
in AppContainer (at renderApplication.js:39)
React Code:
/* eslint-disable class-methods-use-this */
/* eslint-disable global-require */
/* eslint-disable react/destructuring-assignment */
import * as React from 'react';
import {
SafeAreaView,
ImageBackground,
Button,
TextInput,
View
} from 'react-native';
import { Actions } from 'react-native-router-flux';
import { login } from '../services/user';
import * as style from './style/design';
class Login extends React.Component {
constructor() {
super();
this.state = {
username: '',
password: ''
};
}
async login() {
const ret = await login(this.state.username, this.state.password);
if (ret === 'denied') {
console.log(`Sono dentro con : ${ret.toString()}`);
} else {
Actions.home();
}
}
gotoregister() {
Actions.register();
}
render() {
return (
<View style={style.container}>
<ImageBackground
source="../assets/images/backgroundhome.jpg"
style={style.imgBackground}
>
<SafeAreaView>
<TextInput
style={style.textinput}
onChangeText={(text) => {
this.setState({ username: text });
}}
value={this.state.username}
placeholder="insert username"
/>
<TextInput
style={style.textinput}
onChangeText={(text) => {
this.setState({ password: text });
}}
value={this.state.password}
placeholder="insert password"
/>
<Button title="Login" onPress={() => this.login()} />
<Button
title="Register to fit"
onPress={() => this.gotoregister()}
/>
</SafeAreaView>
</ImageBackground>
</View>
);
}
}
export default Login;
design.js file:
import { StyleSheet } from 'react-native';
export const styles = StyleSheet.create({
container: { alignItems: 'center', flex: 1, justifyContent: 'center' }
});
export const style = StyleSheet.create({
image: {
height: 100,
width: 260
},
imgBackground: {
flex: 1,
height: '100%',
width: '100%'
},
textinput: {
backgroundColor: '#FFFFFF',
borderColor: '#D3D3D3',
borderRadius: 20,
borderWidth: 2,
height: 50,
marginTop: 10,
textAlign: 'center'
}
});
style.container is undefined. Try merging the styles in the design.js file.
export const style = StyleSheet.create({
container: {
alignItems: 'center',
flex: 1,
justifyContent: 'center'
},
image: {
height: 100,
width: 260
},
imgBackground: {
flex: 1,
height: '100%',
width: '100%'
},
textinput: {
backgroundColor: '#FFFFFF',
borderColor: '#D3D3D3',
borderRadius: 20,
borderWidth: 2,
height: 50,
marginTop: 10,
textAlign: 'center'
}
});

TypeError: navigation.getParam is not a function - react native

This is the error I get-->
I have a HomeFeed.js where I list all my articles and when you click on each article you get taken to the Content.js where you can see the article details/content.
In the HomeFeed.js, when you press on the article this happens-->
..........................................................................................................................................................................................................................................................................................................................................................................................
onPress={() => {
this.props.navigation.navigate("Content", {
articlekey: `${JSON.stringify(item.key)}`,
});
}}
..........................................................................................................................................................................................................................................................................................................................................................................................
In my Content.js, I have the below:
import React, { Component } from "react";
import { StyleSheet, ScrollView, ActivityIndicator, View } from "react-native";
import { Text, Card } from "react-native-elements";
import firebase from "../../firebase";
class Content extends Component {
static navigationOptions = {
title: "Content",
};
constructor() {
super();
this.state = {
isLoading: true,
article: {},
key: "",
};
}
componentDidMount() {
const { navigation } = this.props;
const ref = firebase
.firestore()
.collection("articles")
.doc(JSON.parse(navigation.getParam("articlekey")));
ref.get().then((doc) => {
if (doc.exists) {
this.setState({
article: doc.data(),
key: doc.id,
isLoading: false,
});
} else {
console.log("No such document!");
}
});
}
render() {
if (this.state.isLoading) {
return (
<View style={styles.activity}>
<ActivityIndicator size="large" color="#0000ff" />
</View>
);
}
return (
<ScrollView>
<Card style={styles.container}>
<View style={styles.subContainer}>
<View>
<Text h3>{this.state.article.title}</Text>
</View>
<View>
<Text h5>{this.state.article.content}</Text>
</View>
</View>
</Card>
</ScrollView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
},
subContainer: {
flex: 1,
paddingBottom: 20,
borderBottomWidth: 2,
borderBottomColor: "#CCCCCC",
},
activity: {
position: "absolute",
left: 0,
right: 0,
top: 0,
bottom: 0,
alignItems: "center",
justifyContent: "center",
},
detailButton: {
marginTop: 10,
},
});
export default Content;
The problem is with your get method of parameters. With react-navigation version 5.X or upper, you need to get params with route.
SOLUTION
Change componentDidMount( ) like this
componentDidMount() {
// const { navigation } = this.props; remove this
const { articlekey } = this.props.route.params; //add this
const ref = firebase
.firestore()
.collection("articles")
.doc(JSON.parse(articlekey));
ref.get().then((doc) => {
if (doc.exists) {
this.setState({
article: doc.data(),
key: doc.id,
isLoading: false,
});
} else {
console.log("No such document!");
}
});
}

how you hide uids in firebase in react native?

i want hide the uids from displaying on my display page, right now it displays -LrM8rlKq1-dSW6XRt0_({"color: 'blue"}), but i just want it to display ({"color: 'blue"}) without uid(-LrM8rlKq1-dSW6XRt0_) beside it enter image description here
enter image description here
import React, { Component } from 'react';
import { View, Text, StyleSheet, Button, TextInput, TouchableOpacity } from 'react-native';
import firebase from './firebase';
export default class App extends Component {
carDatabase = firebase.database().ref('car');
state = { cars: {}, selectedId: '' }
// Read
componentDidMount() {
this.carDatabase.on('value', cars => {
const carsJSON = cars.val();
this.setState({ cars: carsJSON === null ? {} : carsJSON });
})
// this.carDatabase.push({color: 'yellow'})
}
// Create
create() {
this.carDatabase.push({color: 'yellow'})
this.setState({selectedId: ''})
}
// Update
update() {
this.carDatabase.child(this.state.selectedId).set({color: 'blue'})
this.setState({selectedId: ''})
}
// Delete
deleteCar() {
if(this.state.selectedId === '') {
return;
}
this.carDatabase.child(this.state.selectedId).set(null)
this.setState({selectedId: ''})
}
render() {
return (
<View style={styles.container}>
<TextInput value={this.state.selectedId} style={styles.textInput}></TextInput>
<Button title="create" onPress={() => this.create()}></Button>
<Button title="update" onPress={() => this.update()}></Button>
<Button title="delete" onPress={() => this.deleteCar()}></Button>
{
Object.keys(this.state.cars).map( (carId, index) => (
<Text style={{color: this.state.cars[carId].color}}>hi !</Text>
)
}
{/* <Text>{JSON.stringify(this.state.cars, null, 2)}</Text> */}
</View>
);
}
}
const styles = StyleSheet.create({
textInput: {
backgroundColor: 'green',
height: 30,
width: '100%'
},
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center'
}
});

How can I switch firebase configuration using toggle in react native

I am using reactnative, redux and firebase.
Now i want to config two diff firebase env one is development and other one is production.
I implemented a toggle to switch the firebase diff account.
i put firebase config file in ./App.js
import React, { Component } from 'react';
import { Provider } from 'react-redux';
import firebase from 'firebase';
import store from './src/config/store';
import AppNavigation from './src/navigation';
class App extends Component {
componentWillMount() {
firebase.initializeApp({
apiKey: 'AIzaSyAandJABqieT3fXk2palvAgbYz5B8y9EsM',
authDomain: 'practiciaappsubu.firebaseapp.com',
databaseURL: 'https://practiciaappsubu.firebaseio.com',
projectId: 'practiciaappsubu',
storageBucket: 'practiciaappsubu.appspot.com',
messagingSenderId: '753143230840'
});
firebase.auth().onAuthStateChanged((user) => {
if (user) {
console.log('logged In');
} else {
console.log('not looged in');
}
});
}
render() {
return (
<Provider store={store}>
<AppNavigation />
</Provider>
);
}
}
export default App;
The toggle is there is Home component. So, after change the toggle from Home componet, how can i get the toggle status in ./App.js file?
The Home.js (component)
import React, { Component } from 'react';
import {
Text,
View,
Image,
ScrollView,
Switch
} from 'react-native';
import { connect } from 'react-redux';
import { NavigationActions } from 'react-navigation';
import { Button, Section } from './helpers';
import { userType } from '../config/MasterData';
import { firebaseEnvAction } from '../actions/HomeAction';
class Home extends Component {
static navigationOptions = {
title: '.: Practicia :.'
};
onPressSignupAs(userInfo) {
// Navigate to sign up page with the user information
console.log(userInfo);
}
onPressLogin() {
// Navigate to login page
const navigateToLogin = NavigationActions.navigate({
routeName: 'login',
params: {}
});
this.props.navigation.dispatch(navigateToLogin);
}
firebaseEnv(val) {
this.props.firebaseEnvAction(val);
}
render() {
return (
<ScrollView contentContainerStyle={styles.contentContainer}>
<View style={styles.container}>
<View style={styles.logoContainer}>
<Image
style={styles.logo}
source={require('../assets/images/logo.png')}
/>
</View>
<View style={styles.contentArea}>
<Text style={styles.signInAs}>Sign Up As...</Text>
<Section>
<Button
onPress={this.onPressSignupAs.bind(this, userType.teacher)}
>
{userType.teacher.showText}
</Button>
</Section>
<Section>
<Button
onPress={this.onPressSignupAs.bind(this, userType.parent)}
>{userType.parent.showText}</Button>
</Section>
<Section>
<Button
onPress={this.onPressSignupAs.bind(this, userType.student)}
>
{userType.student.showText}
</Button>
</Section>
</View>
<View style={styles.LoginBox}>
<Text style={styles.LoginText}>Already have an account? </Text>
<Section>
<Button
style={styles.buttonLogin}
styleText={styles.buttonText}
onPress={this.onPressLogin.bind(this)}
>
Login
</Button>
</Section>
<Section>
<Text style={styles.firebaseText}>Firebase:
<Switch
value={this.props.HomeReducer.firebaseToggle}
onValueChange={(val) => this.firebaseEnv(val)}
disabled={false}
activeText={'Prod'}
inActiveText={'Dev'}
circleSize={30}
barHeight={1}
circleBorderWidth={3}
backgroundActive={'green'}
backgroundInactive={'gray'}
circleActiveColor={'#30a566'}
circleInActiveColor={'#000000'}
/>
</Text>
</Section>
</View>
</View>
</ScrollView>
);
}
}
const styles = {
firebaseText: {
fontSize: 20
},
contentContainer: {
flex: 1
},
container: {
backgroundColor: '#FFFFFF',
borderRadius: 4,
borderWidth: 0.5,
borderColor: '#9DDAEE',
flex: 1,
padding: 10,
justifyContent: 'center',
},
userType: {
fontSize: 23,
fontWeight: 'bold',
backgroundColor: '#3BAFDA',
margin: 10,
padding: 10,
textAlign: 'center',
color: '#fff',
},
contentArea: {
marginLeft: 40,
marginRight: 40,
marginBottom: 20,
},
logoContainer: {
justifyContent: 'center',
alignItems: 'center',
marginTop: 10,
marginBottom: 40,
},
logo: {
width: 250,
height: 75,
},
signInAs: {
fontSize: 20,
textAlign: 'center',
marginBottom: 10,
},
LoginBox: {
marginTop: 20,
marginLeft: 40,
marginRight: 40,
},
LoginText: {
fontSize: 15,
textAlign: 'center',
marginBottom: 10,
},
buttonLogin: {
backgroundColor: '#C4C4C4',
},
buttonText: {
color: '#000000',
}
};
const mapStateToProps = (state) => {
return state;
};
const mapDispatchToProps = {
firebaseEnvAction
};
export default connect(mapStateToProps, mapDispatchToProps)(Home);
You'll want to dispatch an action when the switch is toggled that tears down your firebase instance (firebase.initializeApp({...});) and initializes a new firebase app with the credentials you want. This means you'll probably want to dispatch a new initilizeFirebase action in your App.js componentWillMount function. Then your Home.js should pull the configured firebase instance from the store. This also means you'll probably want to keep your firebase instance in the store as well.

Resources