adding data to firestore on user input - javascript

Hi im trying to add data to firestore as shown below, but its saying that "undefined is not an object (evaluating "this.state"), i'm taking user email and name etc in by a text input box, why is this failing?
thank you!
import React, {useContext, useState} from 'react'
import { StyleSheet, Text, View, Image, Dimensions, TextInput, Button, TouchableOpacity} from 'react-native'
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view'
import { StatusBar } from 'expo-status-bar'
import * as firebase from 'firebase'
import 'firebase/firestore';
import { AuthContext } from '../navigations/AuthProvider'
import {Alert} from 'react-native';
export default class Register extends React.Component {
static navigationOptions = {
headerShown: false
};
constructor(props) {
super(props);
this.state = {
name: "",
email: "",
password: "",
errorMessage: ""
};
}
handleSignUp = () => {
try {
firebase.auth().createUserWithEmailAndPassword(this.state.email, this.state.password)
.then(function(user){
const user2 = firebase.auth().currentUser;
firebase.firestore().collection('users').add({
email: user2.email,
name: user2.displayName
})
});
} catch (err) {
Alert.alert('There is something wrong!', err.message);
}
}
render () {
return (
<KeyboardAwareScrollView>
<View style={styles.container}>
<StatusBar style="auto"/>
<View style={styles.image_view}>
<Image
source={require("../assets/images/dcuhublogo_higherres.png")}
resizeMode="contain"
resizeMode="center"
style={styles.image_style}>
</Image>
</View>
<View style={{
alignSelf: 'center',
marginTop: -50,
marginBottom: 50
}}>
<Text style={{
textAlign: 'center',
fontSize: 17,
color: '#696868'
}}>{'Welcome to DCU Hub! \nSign up to get started.'} </Text>
</View>
<View style={styles.errorMessage}>
{this.state.errorMessage && <Text style={styles.error}>{this.state.errorMessage}</Text>}
</View>
< View style={styles.top_placeholder}>
<TextInput
style={styles.placeholder_text}
placeholder="FULL NAME" autoCapitalize="none" onChangeText={name => this.setState({name})}
value={this.state.name}
></TextInput>
</View>
<View style={styles.placeholder_style}>
<TextInput
style={styles.placeholder_text}
placeholder="DCU EMAIL" autoCapitalize="none" onChangeText={email => this.setState({email})}
value={this.state.email}
></TextInput>
</View>
<View style={styles.placeholder_style}>
<TextInput
style={styles.placeholder_text}
secureTextEntry={true} // SECURE PASSWORD ie hides the texts
placeholder="PASSWORD" secureTextEntry autoCapitalize="none" onChangeText={password => this.setState({password})}
value={this.state.password}
></TextInput>
</View>
{/* THIS ALSO USES FIREBASE AUTHENTICATION
ONCED SIGNED UP, IT SHOULD TAKE THE USER TO THE
CREATE PROFILE SECTION/SCREEN */}
<View>
<Button2 text='SIGN UP' onPress={this.handleSignUp}/>
</View>
<View style={styles.to_signin}>
<Text style={{fontSize: 18}}> Already have an account? </Text>
<TouchableOpacity onPress={() => this.props.navigation.navigate('Login')}>
<Text style={{color: "#d40059", fontSize: 18}}>Sign In</Text>
</TouchableOpacity>
</View>
</View>
</KeyboardAwareScrollView>
);
}
}
I've even tried to use a constructor,
constructor(props) {
super(props);
this.state = {
name: "",
email: "",
password: "",
errorMessage: ""
};
}
and this also fails, what am I doing wrong?
thanks so much!

Related

Login/Register problem in react native app mobile using laravel backend

I'm a beginner in react native, I'm struggling into Login/Register functions, in my metro, it doesn't show login successfully just like in my backend, please help me!
This is my backend result.
And this is my code Login.js
In my metro, it shows no results, as It should show success:true or something like that as many tutorials I checked on youtube, thanks in advance.
import React, { useState } from 'react'
import { TouchableOpacity, StyleSheet, View } from 'react-native'
import { Text } from 'react-native-paper'
import Background from '../components/Background'
import Logo from '../components/Logo'
import Header from '../components/Header'
import Button from '../components/Button'
import TextInput from '../components/TextInput'
import BackButton from '../components/BackButton'
import { theme } from '../core/theme'
import { emailValidator } from '../helpers/emailValidator'
import { passwordValidator } from '../helpers/passwordValidator'
export default function login({ navigation }) {
const [email_user, setEmail_user] = useState({ value: '', error: '' })
const onLoginPressed = () => {
const emailError = emailValidator(email_user.value)
const passwordError = passwordValidator(password.value)
if (emailError || passwordError) {
setEmail_user({ ...email_user, error: emailError })
setPassword({ ...password, error: passwordError })
return
}
navigation.reset({
index: 0,
routes: [{ name: 'Home' }],
})
}
const [password, setPassword] = useState("");
const login = () => {
const data = { email_user: email_user, password: password };
axios.post('http://10.0.2.2:8000/api/auth/login', data).then((response) => {
if (response.data.error) {
alert(response.data.error);
} else {
sessionStorage.setItem("accessToken", response.data);
history.push("/");
}
});
};
return (
<Background>
<BackButton goBack={navigation.goBack} />
<Logo />
<Header></Header>
<TextInput
label="Email"
returnKeyType="next"
value={email_user.value}
onChangeText={(text) => setEmail_user({ value: text, error: '' })}
error={!!email_user.error}
errorText={email_user.error}
autoCapitalize="none"
autoCompleteType="email"
textContentType="emailAddress"
keyboardType="email-address"
/>
<TextInput
label="Password"
returnKeyType="done"
value={password.value}
onChangeText={(text) => setPassword({ value: text, error: '' })}
error={!!password.error}
errorText={password.error}
secureTextEntry
/>
<View style={styles.forgotPassword}>
<TouchableOpacity
onPress={() => navigation.navigate('reset')}
>
<Text style={styles.forgot}>Forgot your password?</Text>
</TouchableOpacity>
</View>
<Button mode="contained" onPress={onLoginPressed}>
Login
</Button>
<View style={styles.row}>
<Text>Don’t have an account? </Text>
<TouchableOpacity onPress={() => navigation.replace('register')}>
<Text style={styles.link}>Sign up</Text>
</TouchableOpacity>
</View>
</Background>
)
}
const styles = StyleSheet.create({
forgotPassword: {
width: '100%',
alignItems: 'flex-end',
marginBottom: 24,
},
row: {
flexDirection: 'row',
marginTop: 4,
},
forgot: {
fontSize: 13,
color: theme.colors.secondary,
},
link: {
fontWeight: 'bold',
color: theme.colors.blue,
},
})

How to keep user logged in after logging in to his account forever using firebase

hey i tried so many ways and research about it too much but still i am facing this error so can someone pls tell me how to keep user logged in after logging in to his account forever using firebase
import React, { useState } from "react";
import {
View,
Text,
TextInput,
Button,
StyleSheet,
Pressable,
TouchableOpacity,
Alert,
} from "react-native";
import { firebase } from "../../firebase";
import { Formik } from "formik";
import * as Yup from "yup";
import Validator from "email-validator";
const LoginForm = ({ navigation }) => {
const LoginFormSchema = Yup.object().shape({
email: Yup.string().email().required("An email is required"),
password: Yup.string()
.required()
.min(6, "Your password has to have at least 6 characters"),
});
const onLogin = async (email, password) => {
try {
await firebase.auth().signInWithEmailAndPassword(email, password);
console.log("Firebase Login Successfully" + email, password);
} catch (error) {
Alert.alert(error.message);
}
};
return (
<View style={styles.wrapper}>
<Formik
initialValues={{ email: "", password: "" }}
onSubmit={(values) => {
onLogin(values.email, values.password);
}}
validationSchema={LoginFormSchema}
validateOnMount={true}
>
{({ handleChange, handleBlur, handleSubmit, values, isValid }) => (
<>
<View
style={[
styles.inputField,
{
borderColor:
values.email.length < 1 || Validator.validate(values.email)
? "#ccc"
: "red",
},
]}
>
<TextInput
placeholder="Phone Number, username or email"
autoCapitalize="none"
keyboardType="email-address"
textContentType="emailAddress"
autoFocus={true}
onChangeText={handleChange("email")}
onBlur={handleBlur("email")}
value={values.email}
/>
</View>
<View
style={[
styles.inputField,
{
borderColor:
1 > values.password.length || values.password.length >= 6
? "#ccc"
: "red",
},
]}
>
<TextInput
placeholder="Password"
autoCapitalize="none"
autoCorrect={false}
secureTextEntry={true}
textContentType="password"
onChangeText={handleChange("password")}
onBlur={handleBlur("password")}
value={values.password}
/>
</View>
<View style={{ alignItems: "flex-end", marginBottom: 30 }}>
{/* <Text style={{ color: "#68B0F5" }}>Forgot Password?</Text> */}
</View>
<View style={{ justifyContent: "center", alignItems: "center" }}>
<Pressable
titleSize={20}
style={styles.button(isValid)}
disabled={!isValid}
onPress={handleSubmit}
>
<Text style={styles.buttonText}>Log In</Text>
</Pressable>
</View>
<View style={styles.signupContainer}>
<Text>Don't have an account?</Text>
<TouchableOpacity onPress={() => navigation.push("SignupScreen")}>
<Text style={{ color: "#68B0F5" }}>Sign Up</Text>
</TouchableOpacity>
</View>
</>
)}
</Formik>
</View>
);
};
const styles = StyleSheet.create({
wrapper: {
marginTop: 80,
},
inputField: {
borderRadius: 4,
padding: 12,
backgroundColor: "#FAFAFA",
marginBottom: 10,
borderWidth: 1,
},
button: (isValid) => ({
backgroundColor: isValid ? "#DC143C" : "#f56991",
alignItems: "center",
justifyContent: "center",
minHeight: 42,
borderRadius: 50,
width: "60%",
}),
buttonText: {
color: "white",
fontWeight: "600",
fontSize: 20,
},
signupContainer: {
flexDirection: "row",
width: "100%",
justifyContent: "center",
marginTop: 50,
},
});
export default LoginForm;
and i am creating a Instagram clone with the help of this tutorial : https://www.youtube.com/watch?v=UbixZZDjrdU&t=390s
You should ask your user again for the password and re-authendicate him with:
const credential = EmailAuthProvider.credential(email, password);
const user = firebase.auth.currentUser;
if (user) reauthenticateWithCredential(user, credential);
If the above doesn't work, use your login function.
It is not suggested though to save user's password in AsyncStorage and re-use it to re-log him in an every refresh.

How to show Loading on Button press POST request in React Native?

I am making one Register page in my React Native project. In this page, after filling the form when user presses the Register button one POST request is called. While the POST request response takes some time, I want to show Loading in my screen until I get any response from server.
Here's my code-
import React from 'react';
import { StyleSheet, Text, View, ScrollView, TextInput,
Button,
TouchableHighlight,
Image,
Alert, ActivityIndicator } from 'react-native';
class WelcomeScreen extends React.Component {
constructor() {
super();
this.state = {
first_name:'',
last_name:'',
email : '',
mobile: '',
password:'',
confirmPassword:'',
showLoader:false
}
};
showLoader = () => { this.setState({ showLoader:true }); };
hideLoader = () => { this.setState({ showLoader:false }); };
doSignup(){
this.showLoader();
}
updateValue(text, field) {
if(field == 'first_name') {
this.setState({
first_name: text
})
}
else if(field == 'last_name') {
this.setState({
last_name : text
})
}
else if(field == 'email') {
this.setState({
email : text
})
}
else if(field == 'mobile') {
this.setState({
mobile : text
})
}
else if(field == 'password') {
this.setState({
password : text
})
}
else if(field == 'confirmPassword') {
this.setState({
confirmPassword : text
})
}
}
onClickListener = (viewId) => {
Alert.alert("Alert", "Button pressed "+viewId);
}
submit() {
let collection = {}
collection.first_name = this.state.first_name,
collection.last_name = this.state.last_name,
collection.email = this.state.email,
collection.mobile = this.state.mobile
collection.password = this.state.password,
console.log('#HELLO:', collection);
var url = 'my url';
if(collection.first_name != '' && collection.last_name != '' &&
collection.email != '' && collection.mobile != '' &&
collection.password != '') {
if(this.state.password === this.state.confirmPassword) {
fetch(url, {
method: 'POST',
body: JSON.stringify(collection),
headers: new Headers({
'Content-Type' : 'application/json',
'token': 'token'
})
}).then(res => res.json())
.catch(error=> console.error('Error:', error))
.then(response => console.log('Success:', response));
} else {
Alert.alert('Password and Confirm Password didn\'t match');
}
} else {
Alert.alert('Please fill up the required field');
}
}
render() {
return (
<ScrollView keyboardShouldPersistTaps={'handled'}>
<View style={styles.container}>
<View style={styles.inputContainerEmail}>
<Image style={styles.inputIcon} source={{uri: 'https://png.icons8.com/message/ultraviolet/50/3498db'}}/>
<TextInput style={styles.inputs}
placeholder="Email"
keyboardType="email-address"
underlineColorAndroid='transparent'
onChangeText={(text) => this.updateValue(text, 'email')}/>
</View>
<View style={styles.inputContainer}>
<Image style={styles.inputIcon} source={{uri: 'https://png.icons8.com/key-2/ultraviolet/50/3498db'}}/>
<TextInput style={styles.inputs}
placeholder="Password"
secureTextEntry={true}
underlineColorAndroid='transparent'
onChangeText={(text) => this.updateValue(text, 'password')}/>
</View>
<View style={styles.inputContainer}>
<Image style={styles.inputIcon} source={{uri: 'https://png.icons8.com/key-2/ultraviolet/50/3498db'}}/>
<TextInput style={styles.inputs}
placeholder="Confirm Password"
secureTextEntry={true}
underlineColorAndroid='transparent'
onChangeText={(text) => this.updateValue(text, 'confirmPassword')}/>
</View>
<View style={styles.inputContainer}>
<Image style={styles.inputIcon} source={{uri: 'https://img.icons8.com/ultraviolet/40/000000/administrator-male.png'}}/>
<TextInput style={styles.inputs}
placeholder="First Name"
secureTextEntry={true}
underlineColorAndroid='transparent'
onChangeText={(text) => this.updateValue(text, 'first_name')}/>
</View>
<View style={styles.inputContainer}>
<Image style={styles.inputIcon} source={{uri: 'https://img.icons8.com/ultraviolet/40/000000/administrator-male.png'}}/>
<TextInput style={styles.inputs}
placeholder="Last Name"
secureTextEntry={true}
underlineColorAndroid='transparent'
onChangeText={(text) => this.updateValue(text, 'last_name')}/>
</View>
<View style={styles.inputContainer}>
<Image style={styles.inputIcon} source={{uri: 'https://img.icons8.com/ultraviolet/40/000000/phone.png'}}/>
<TextInput style={styles.inputs}
placeholder="Phone No."
secureTextEntry={true}
underlineColorAndroid='transparent'
textContentType='telephoneNumber'
onChangeText={(text) => this.updateValue(text, 'mobile')}/>
</View>
<TouchableHighlight style={[styles.buttonContainer, styles.loginButton]} onPress=
{()=>{this.submit(); this.doSignup;}}>
<Text style={styles.loginText}>Register</Text>
</TouchableHighlight>
<TouchableHighlight style={styles.buttonContainer} onPress={() => this.onClickListener('restore_password')}>
<Text>Forgot your password?</Text>
</TouchableHighlight>
<TouchableHighlight style={styles.buttonContainerRegister} onPress={() => this.onClickListener('register')}>
<Text>Sign In</Text>
</TouchableHighlight>
</View>
<View style={{ position: 'absolute', top:"50%",right: 0, left: 0 }}>
<ActivityIndicator animating={this.state.showLoader} size="large" color="red" />
</View>
</ScrollView>
);
}
}
I have tried the following solution-
Show loader when button is clicked in react native
But none of them worked in my case. I am not understanding why the Loading is not showing after pressing the Register button as the response is taking some time. So, it would be very nice if someone help to find the problem and give advice to solve it.
You placed the loading view inside the ScrollView, which probably messes up the positioning. Better to wrap the ScrollView in a containing View and place the loading View as a sibling of the ScrollView, show it using conditional rendering.
render() {
return <View style={{flex: 1}}>
<ScrollView style={{flex: 1}}>
{/* contents here */}
</ScrollView>
{
this.state.showLoader && <View style={{ position: 'absolute', top:"50%",right: 0, left: 0 }}>
<ActivityIndicator size="large" color="red" />
</View>
}
</View>;
}

ReactNative TextInput not letting me type

For both iOS and Android simulators
The text just disappears/flickers when I start typing. I tried having an initial state of texts with some value instead of keeping it empty. With this the TextInput sticks to this initial state and does not update itself with new text entered.
I think the state is not updating with 'onChangeText' property, but I am not completely sure.
People have seem to solve this, as they had few typos or missing pieces in code. However I have checked mine thoroughly.
Please help if I have missed anything in the below code.
LoginForm.js
import React, { Component } from 'react';
import { Card, Button, CardSection, Input } from './common';
class LoginForm extends Component {
state = { email: '', password: '' }
render() {
return (
<Card>
<CardSection>
<Input
label="Email"
placeHolder="user#gmail.com"
onChangeText={text => this.setState({ email: text })}
value={this.state.email}
/>
</CardSection>
<CardSection>
<Input
secureTextEntry
label="Password"
placeHolder="password"
onChangeText={text => this.setState({ password: text })}
value={this.state.password}
/>
</CardSection>
<CardSection>
<Button>
Log In
</Button>
</CardSection>
</Card>
);
}
}
export default LoginForm;
Input.js
import React from 'react';
import { TextInput, View, Text } from 'react-native';
const Input = ({ label, value, onChangeText, placeholder, secureTextEntry }) => {
const { inputStyle, labelStyle, containerStyle } = styles;
return (
<View style={containerStyle}>
<Text style={labelStyle}>{label}</Text>
<TextInput
secureTextEntry={secureTextEntry}
placeholder={placeholder}
autoCorrect={false}
style={inputStyle}
value={value}
onChangeText={onChangeText}
/>
</View>
);
};
const styles = {
inputStyle: {
color: '#000',
paddingRight: 5,
paddingLeft: 5,
fontSize: 18,
lineHeight: 23,
flex: 2
},
labelStyle: {
fontSize: 18,
paddingLeft: 20,
flex: 1
},
containerStyle: {
height: 40,
flex: 1,
flexDirection: 'row',
alignItems: 'center'
}
};
export { Input };
The only way to solve this was to change the way the values of TextInput fields are updated, with this code below.
value={this.state.email.value}
value={this.state.password.value}
You problem is how the Input component is written.
There is a render function written inside the stateless component which is not a React class component:
const Input = ({ label, value, onChangeText, placeHolder, secureTextEntry }) => ( // ← remove the wrapping parentheses
{
render() { // <--- this should not be here
↑
const { inputStyle, labelStyle, containerStyle } = styles;
return (
<View style={containerStyle} >
<Text style={labelStyle}>{label}</Text>
<TextInput
secureTextEntry={secureTextEntry}
autoCorrect={false}
placeholder={placeHolder}
style={inputStyle}
onChangeText={onChangeText}
value={value}
underlineColorAndroid="transparent"
/>
</View>
);
}
}
);
Change it to this:
const Input = ({ label, value, onChangeText, placeHolder, secureTextEntry }) => {
const { inputStyle, labelStyle, containerStyle } = styles;
return (
<View style={containerStyle} >
<Text style={labelStyle}>{label}</Text>
<TextInput
secureTextEntry={secureTextEntry}
autoCorrect={false}
placeholder={placeHolder}
style={inputStyle}
onChangeText={onChangeText}
value={value}
underlineColorAndroid="transparent"
/>
</View>
);
};
See running example

Inserting data from array of objects to array React Native

I am trying to get user input, create an array of objects from userInput and save that array of objects into an array. Below is code I have written, but no output.
import React, { Component } from 'react';
import {Text, View, StyleSheet, TextInput, Image, TouchableOpacity, ListView} from 'react-native';
//import {Actions} from 'react-native-router-flux';
const count = 0;
export default class SecondPage extends Component {
constructor(props) {
super(props);
this.state = {
quan:'',
desc:'',
amt:'',
dataStorage :[],
data: { quantity: this.quan, description: this.desc, amount: this.amt },
}
}
_add(){
console.log('Add button pressed');
this.state.dataStorage[count].push(this.state.data);
console.log(this.state.data);
count++;
}
render(){
return(
<View style={styles.container}>
<View style={styles.itemDescription}>
<Text style={styles.itemDescriptionText}>QUANTITY</Text>
<Text style={styles.itemDescriptionText}>DESCRIPTION</Text>
<Text style={styles.itemDescriptionText}>AMOUNT</Text>
<TouchableOpacity style={styles.addButton} onPress={this._add}>
<Text style={styles.addButtonText}>ADD</Text>
</TouchableOpacity>
</View>
<View style={styles.rowsOfInput}>
<TextInput style = {styles.nameInput}
onChangeText={(text) => this.setState({quan: text})}
value = {this.state.quan}
autoCapitalize='none'
autoCorrect={false}
returnKeyType="next"
keyboardAppearance="dark"
/>
<TextInput style = {styles.nameInput}
onChangeText={(text) => this.setState({desc: text})}
value = {this.state.desc}
autoCapitalize='none'
autoCorrect={false}
returnKeyType="next"
keyboardAppearance="dark"
/>
<TextInput style = {styles.nameInput}
onChangeText= {(text) => this.setState({amt: text})}
value = {this.state.amt}
autoCapitalize='none'
autoCorrect={false}
returnKeyType="next"
keyboardAppearance="dark"
/>
</View>
</View>
)}
}
const styles = StyleSheet.create({
container: {
flexDirection: 'column',
},
itemDescription: {
marginTop:20,
backgroundColor:'#00CED1',
flexDirection:'row',
justifyContent:'space-between',
},
itemDescriptionText:{
fontSize:12,
color:'white',
},
addButton:{
borderWidth:1,
height:20,
borderRadius:5,
overflow:'hidden',
backgroundColor:'red',
},
addButtonText:{
paddingLeft:10,
paddingRight:10,
},
nameInput:{
flex:1,
height: 20,
textAlignVertical:'bottom',
paddingLeft: 5,
paddingRight: 5,
fontSize: 12,
backgroundColor:'#E0FFFF',
},
hairLine:{
height:1,
backgroundColor:'black',
marginTop:0,
marginLeft:20,
marginRight:20
},
rowsOfInput:{
// flex:1,
flexDirection:'row',
justifyContent:'space-around'
},
});
Whats wrong in the code? I want to store userInput for each entry into QUANTITY, DESCRIPTION, AMOUNT as array of object.
One of your issues is a scoping issue. Change your _add method to this.
_add = () => {
let dataStorage = [{amt: this.state.amt, quan: this.state.quan, desc: this.state.desc}, ...this.state.dataStorage]
console.log(dataStorage)
this.setState({dataStorage})
}
Also, your data property on state will never work and is unnecessary.
Here is an example.
It still won't display anything because you do nothing with dataStorage.

Categories

Resources