there! I'm using Firebase for authentication. Everytime, when I try to register a new user, I receive an alert from Firebase, which says that the email address is badly formatted (auth/invalid-email). But if I try to sign in, it works perfectly. I just dont get what the error could be.
RegisterScreen:
const RegisterScreen = ({ navigation }) => {
const [email, setEmail] = useState("");
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const register = () => {
auth.createUserWithEmailAndPassword(email, password).then((authUser) => {
authUser.user.updateProfile({
displayName: username
});
})
.catch((error) => {alert(error.message)});
};
return (
<KeyboardAvoidingView behavior="padding" style={styles.container}>
<Text h3 style={styles.title}>Register</Text>
<View style={styles.inputContainer}>
<Input
style={styles.inputText}
placeholder="Email"
placeholderTextColor="#003f5c"
onChangeText={(text) => setEmail(text)}/>
<Input
style={styles.inputText}
placeholder="Benuztername"
placeholderTextColor="#003f5c"
onChangeText={(text) => setUsername(text)}/>
<Input
style={styles.inputText}
placeholder="Password"
secureTextEntry
placeholderTextColor="#003f5c"
onChangeText={(text) => setPassword(text)}/>
<View style={styles.buttonStyle}>
<Button
title="Register"
containerStyle={styles.button}
onPress={register, singIn} />
<Button
title="Back"
type="outline"
containerStyle={styles.button}
onPress={() => navigation.navigate("Login") }/>
</View>
</View>
</KeyboardAvoidingView>
);
};
export default RegisterScreen;
LoginScreen
const LoginScreen = ({ navigation }) => {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const singIn = () => {
auth.signInWithEmailAndPassword(email, password).catch((error) => {alert(error.message)});
};
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged((authUser) => {
if(authUser){
navigation.replace("Home");
}
});
return unsubscribe;
}, []);
return (
<KeyboardAvoidingView behavior="padding" style={styles.container}>
<Text h3 style={styles.title}>Login</Text>
<View style={styles.inputContainer}>
<Input
style={styles.inputText}
placeholder="Email"
placeholderTextColor="#003f5c"
onChangeText={(text) => setEmail(text)}/>
<Input
style={styles.inputText}
placeholder="Password"
secureTextEntry
placeholderTextColor="#003f5c"
onChangeText={(text) => setPassword(text)}/>
<View style={styles.buttonStyle}>
<Button
title="Login"
containerStyle={styles.button}
onPress={singIn} />
<Button
title="Register"
type="outline"
containerStyle={styles.button}
onPress={() => navigation.navigate("Register") }/>
</View>
</View>
</KeyboardAvoidingView>
);
};
export default LoginScreen;
Related
I'm trying to append elements to my in react native, using this.state.
But it doesn't return the Text element. My View stays empty...can anyone help?
I'm using this as a reference.
function App() {
const {register, setValue, handleSubmit} = useForm();
this.state = {message: []};
useEffect(() => {
register('author');
register('message');
}, [register]);
var socket = io.connect('http://localhost:3000/');
const onSubmit = data => {
renderMessage(data);
socket.emit('sendMessage', data);
};
socket.on('receivedMessage', function (data) {
renderMessage(data);
});
const renderMessage = data => {
this.state.message.push(data);
};
return (
<View style={styles.sectionContainer}>
<TextInput
style={styles.sectionAuthor}
placeholder="author"
onChangeText={text => setValue('author', text)}
/>
<View style={styles.sectionDescription}>
{this.state.message.map(item => (
<Text>{item.author}</Text>
))}
</View>
<TextInput
style={styles.sectionMessage}
placeholder="Message"
onChangeText={text => setValue('message', text)}
/>
<Button onPress={handleSubmit(onSubmit)} title="Enviar" />
</View>
);
}
You are mixing functional component and class component.
You should use useState to manage state instead of this.state
const [messages,setMessages] = useState([]);
const renderMessage = data => {
setMessages([...messages, data]);
};
then in your rendering, it should use messages.
{messages.map(item => (
<Text>{item.author}</Text>
))}
function App() {
const {register, setValue, handleSubmit} = useForm();
const [message,setMessage] = useState([]);
useEffect(() => {
register('author');
register('message');
}, [register]);
var socket = io.connect('http://localhost:3000/');
const onSubmit = data => {
renderMessage(data);
socket.emit('sendMessage', data);
};
socket.on('receivedMessage', function (data) {
renderMessage(data);
});
const renderMessage = data => {
let new_msg = [...message];
new_msg.push(data);
setMessage(new_msg);
};
return (
<View style={styles.sectionContainer}>
<TextInput
style={styles.sectionAuthor}
placeholder="author"
onChangeText={text => setValue('author', text)}
/>
<View style={styles.sectionDescription}>
{this.state.message.map(item => (
<Text>{item.author}</Text>
))}
</View>
<TextInput
style={styles.sectionMessage}
placeholder="Message"
onChangeText={text => setValue('message', text)}
/>
<Button onPress={handleSubmit(onSubmit)} title="Enviar" />
</View>
);
}
I'm attempting to show a simple loading screen component when the data is connecting to firebase (creating a user, or login in). I have set all the indicators with a useState, although when the loading occurs, the screen doesn't pop up.
My register screen:
export function Register({ navigation }: any) {
const [showModal, setShowModal] = useState(false);
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
if (isLoading) return <Loading />;
}, [isLoading]);
return (
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<>
<Modal
visible={showModal}
text={i18n.t('registerModal.title')}
state="success"
description={i18n.t('registerModal.description')}
buttonText={i18n.t('registerModal.goToLogin')}
navigation={undefined}
setShowModal={setShowModal}
onPress={() => {
navigation.navigate('SignIn');
setShowModal(false);
}}
/>
<Container>
<ArrowContainer>
<ArrowTouchable onPress={() => navigation.goBack(null)}>
<ArrowBack width={24} height={24} />
</ArrowTouchable>
</ArrowContainer>
<TitleContainer>
<Title>{i18n.t('signup.title')}</Title>
</TitleContainer>
<Form setShowModal={setShowModal} setIsLoading={setIsLoading} />
<TextContainer>
<Text>{i18n.t('signup.alreadyHaveAccount')}</Text>
<TouchableText onPress={() => navigation.navigate('SignIn')}>
<SignUpText>{i18n.t('signup.singIn')}</SignUpText>
</TouchableText>
</TextContainer>
</Container>
</>
</TouchableWithoutFeedback>
);
}
My Form with sets the loading state:
export function Form({ setShowModal, setIsLoading }: any) {
const {
control,
handleSubmit,
formState: { errors },
} = useForm({
resolver: yupResolver(schema),
});
async function handleUserRegister(data: FormData) {
setIsLoading(true);
const incomingData = await registerWithEmailAndPassword(data);
if (incomingData) {
setIsLoading(false);
setShowModal(true);
}
setIsLoading(false);
}
useEffect(() => {
ToastShowManagement(i18n.t('signup.error'), errors);
}, [errors]);
return (
<Container>
<ControlledInput
name="username"
control={control}
icon="at-sign"
placeholder={i18n.t('signup.username')}
error={errors.username}
/>
<ControlledInput
name="name"
control={control}
icon="user"
placeholder={i18n.t('signup.name')}
error={errors.name}
/>
<ControlledInput
control={control}
name="email"
icon="mail"
placeholder={i18n.t('signup.email')}
keyboardType="email-address"
autoCapitalize="none"
error={errors.email}
/>
<ControlledInput
control={control}
name="password"
icon="lock"
placeholder={i18n.t('signup.password')}
secureTextEntry
error={errors.password}
/>
<ControlledInput
control={control}
name="passwordConfirmation"
icon="lock"
placeholder={i18n.t('signup.confirmPassword')}
secureTextEntry
error={errors.passwordConfirmation}
/>
<PrimaryButton
text={i18n.t('signup.button')}
onPress={handleSubmit(handleUserRegister as any)}
style={{ marginTop: 24 }}
/>
</Container>
);
}
The way to apply useEffect is incorrect
useEffect(() => {
if (isLoading) return <Loading />;
}, [isLoading]);
Does not return the element to main thread, the app.js.
You should take away the useEffect hook
export function Register({ navigation }: any) {
const [showModal, setShowModal] = useState(false);
const [isLoading, setIsLoading] = useState(false);
if (isLoading) return <Loading />
return <>...</>;
}
I want to pass a value from my parent function to my child function.
but I don't know what to do.
please help advice
The language I use is react native. I want to send search data to main function
this is my code
Main Function
export default function Home() {
return (
<View>
<HeaderHome Upload={Upload} Uri={Uri} />
</View>
);
}
Second Function
export default function HeaderHome({ Upload, Uri }) {
const navigation = useNavigation();
const [showScrollView, setShowScrollView] = useState(false);
const [search, setSearch] = useState('');
const onPress = () => {
setShowScrollView(!showScrollView);
};
console.log(search);
return (
<View>
{showScrollView ? (
<View>
<TextInput
placeholder="Search..."
placeholderTextColor="#000"
onChangeText={(e) => setSearch(e)}
/>
<TouchableOpacity onPress={() => onPress()}>
<Text>Cancel</Text>
</TouchableOpacity>
</View>
) : (
<View>
<View>
<Ionicons
name="md-search"
style={styles.iconSearch}
onPress={() => onPress()}
/>
<Ionicons
name="person-circle"
onPress={() => navigation.navigate('Menu', { Upload, Uri })}
/>
</View>
</View>
)}
</View>
);
}
Create a callback function that you pass as a prop from Home to HeaderHome. This could look as follows.
export default function Home() {
const [search, setSearch] = useState('')
return (
<View>
<HeaderHome setHomeSearch={setSearch} Upload={Upload} Uri={Uri} />
</View>
);
}
In HeaderHome you can call that function in the onPress function and set the state search in the Home component as follows.
export default function HeaderHome({ Upload, Uri, setHomeSearch }) {
const navigation = useNavigation();
const [showScrollView, setShowScrollView] = useState(false);
const [search, setSearch] = useState('');
const onPress = () => {
setShowScrollView(!showScrollView);
};
console.log(search);
const onSearchSet = (text) => {
setSearch(text)
setHomeSearch(text)
}
return (
<View>
{showScrollView ? (
<View>
<TextInput
placeholder="Search..."
placeholderTextColor="#000"
onChangeText={(e) => onSearchSet(e)}
/>
<TouchableOpacity onPress={() => onPress()}>
<Text>Cancel</Text>
</TouchableOpacity>
</View>
) : (
<View>
<View>
<Ionicons
name="md-search"
style={styles.iconSearch}
onPress={() => onPress()}
/>
<Ionicons
name="person-circle"
onPress={() => navigation.navigate('Menu', { Upload, Uri })}
/>
</View>
</View>
)}
</View>
);
}
I'm making an app in React Native. There are three components I'm currently concerned with:
AllList.js: A screen comprised of a search bar and a FlatList of RowCard.js instances.
RowCard.js: a custom TouchableHighlight component that displays an item from an API, and displays DrinkPopup.js when tapped by using a state stored in AllList.js.
DrinkPopup.js: A custom Modal component that needs to take an ID from whichever RowCard is tapped and use it to make an API call to get its own data.
I can't figure out how to take the ID from the RowCard or FlatList and pass it to DrinkPopup - how should I do it?
Relevant code for AllList:
export default function AllList() {
const [isLoading, setLoading] = useState(true);
const [drinkData,setDrinkData] = useState([]);
const [searchValue, onChangeText] = useState(''); //needed for search
const [reloading, setReloading] = useState(false);
const [modalVisible, setModalVisible] = useState(false); //normal modal visibility handler
useEffect (() => {
fetch('https://www.thecocktaildb.com/api/json/v1/1/search.php?s=' + searchValue)
.then((response) => response.json())
.then((json) => setDrinkData(json.drinks))
.catch((error) => console.error(error))
.finally(() => setLoading(false));
},[drinkData]);
return (
<View style = {styles.screen}>
<View style = {styles.searchSection}>
<TextInput
placeholder="Search Drinks..."
style={styles.input}
onChangeText={text => onChangeText(text)}
value={searchValue}/>
</View>
<FlatList
data={drinkData}
keyExtractor={({ idDrink }, index) => idDrink}
removeClippedSubviews={true}
initialNumToRender={5}
renderItem={({ item }) => (
<RowCard id={item.idDrink} image={item.strDrinkThumb} title={item.strDrink} alcontent={item.strAlcoholic}
ingredient1={item.strIngredient1} ingredient2={item.strIngredient2} ingredient3={item.strIngredient3} setModalVisible={setModalVisible}
/>
)}
extraData={reloading}
/>
<DrinkPopup modalVisible={modalVisible} setModalVisible={setModalVisible}/>
</View>
);
};
Relevant code for RowCard:
const RowCard = (props) => {
return(
<TouchableHighlight
style={styles.rowCard}
activeOpacity={0.6}
underlayColor={"white"}
onPress={() => {props.setModalVisible(true) }}
>
<View style={styles.rowCard}>
<Image source={{uri: props.image, width: 150, height: 150}} />
<View style={styles.textBox}>
<Text style={styles.titleText}>{props.title}</Text>
<Text style={styles.ingredient}> Main ingredients: {props.ingredient1}, {props.ingredient2}, {props.ingredient3} </Text>
</View>
</View>
</TouchableHighlight>
)
};
Relevant code for DrinkPopup:
const DrinkPopup = (props) => {
return(
<Modal isVisible={props.modalVisible}
onBackdropPress={()=>{props.setModalVisible(false)}} //allows closing modal by tapping outside it or back button
onBackButtonPress={()=>{props.setModalVisible(false)}}
animationIn={"slideInUp"}>
<View style={styles.infocard}>
<View style={styles.titleBox}>
<Text style={styles.header}>I HAVE NO IDEA WHAT YOU PICKED</Text>
</View>
</View>
</Modal>
)
}
I have a signout method in my react native app that each time i sign out and try to sign back in my email and password is not remembered in firebase. The database shows the email and password but for some reason when i enter my email and password it doesn't log in. I can't find what i'm doing wrong.
here is my sign in screen
import React, { useState } from 'react'
import { Image, Text, TextInput, TouchableOpacity, View, ImageBackground } from 'react-native'
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
import styles from './styles';
import { firebase } from '../../firebase/config';
export default function LoginScreen({navigation}) {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const onFooterLinkPress1 = () => {
navigation.navigate("Registration")
}
const onFooterLinkPress2 = () => {
navigation.navigate("ResetPassword")
}
const onLoginPress = () => {
firebase
.auth()
.signInWithEmailAndPassword(email, password)
.then((response) => {
const uid = response.user.uid
const usersRef = firebase.firestore().collection('users')
usersRef
.doc(uid)
.get()
.then(firestoreDocument => {
if (!firestoreDocument.exists) {
alert("User does not exist anymore.")
return;
}
const user = firestoreDocument.data()
})
.catch(error => {
alert(error)
});
})
.catch(error => {
alert(error)
})
}
return (
<ImageBackground source={require('../../../assets/backgroundCopySilk.jpg')} style={styles.backgroundImage}>
<View style={styles.container}>
<KeyboardAwareScrollView
style={{ flex: 1, width: '100%' }}
keyboardShouldPersistTaps="always">
<Image
style={styles.logo}
source={require('../../../assets/logoCopy.png')}
/>
<TextInput
style={styles.input}
placeholder='E-mail'
placeholderTextColor="#aaaaaa"
onChangeText={(text) => setEmail(text)}
value={email}
underlineColorAndroid="transparent"
autoCapitalize="none"
/>
<TextInput
style={styles.input}
placeholderTextColor="#aaaaaa"
secureTextEntry
placeholder='Password'
onChangeText={(text) => setPassword(text)}
value={password}
underlineColorAndroid="transparent"
autoCapitalize="none"
/>
<TouchableOpacity
style={styles.button}
onPress={() => onLoginPress()}>
<Text style={styles.buttonTitle}>Log in</Text>
</TouchableOpacity>
<View style={styles.footerView}>
<Text style={styles.footerText}>Don't have an account? <Text onPress={onFooterLinkPress1} style={styles.footerLink}>Sign up</Text></Text>
</View>
<View style={styles.footerView}>
<Text style={styles.footerText}>Forgot Password? <Text onPress={onFooterLinkPress2} style={styles.footerLink}>Reset Here</Text></Text>
</View>
</KeyboardAwareScrollView>
</View>
</ImageBackground>
)
}
Here is my sign out screen
import React from 'react';
import { Image, Text, Linking, TouchableOpacity, View,ImageBackground, Alert } from 'react-native'
import styles from './styles';
import { firebase } from '../../firebase/config';
import { auth } from 'firebase';
import {Spacer} from '../spacer';
export default function ProductScreen({navigation}){
const logOutPress = () => {
try {
auth()
.signOut()
.then(() => { navigation.navigate("Login"),
alert('You have signed out')})
} catch(error){
console.log('Unable to logout')}
}
const yalaPress = () => Alert.alert( "You're about to leave the app",[
{ text: "Cancel",
onPress: ()=> console.log('Cancel Pressed')},
{text: "Ok",
onPress: () => Linking.openURL('https://yalajets.com/')
}],{ cancelable: false } );
return(
<ImageBackground source={require('../../../assets/backgroundCopySilk.jpg')} style={styles.backgroundImage}>
<View style={styles.container}>
<TouchableOpacity
onPress={()=> navigation.navigate('LawnCare')}
style={styles.button}>
<Text style={styles.buttonText}>Luxury Commercial Lawn Care</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.button}>
<Text style={styles.buttonText}>Luxury Vehicle Car Detail</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.button}>
<Text style={styles.buttonText}>Luxury Pharmaceuticals</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.button}>
<Text style={styles.buttonText}>Luxury Personal Fitness</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.button}>
<Text style={styles.buttonText}>Luxury Massage with Catch These Hands</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={yalaPress}
style={styles.button}>
<Text style={styles.buttonText}>Luxury Private Flights with Yala Jets</Text>
</TouchableOpacity>
<Spacer/>
<TouchableOpacity
onPress={()=> logOutPress()}>
<Text style={styles.buttonText}>Log Out</Text>
</TouchableOpacity>
</View>
</ImageBackground>
)
};
also here is my sign up screen
import React, { useState } from 'react'
import { Image, Text, TextInput, TouchableOpacity, View,ImageBackground } from 'react-native'
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
import styles from './styles';
import { firebase } from '../../firebase/config'
export default function RegistrationScreen({navigation}) {
const [firstName, setFirstName] = useState('')
const [lastName, setLastName] = useState('')
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const [confirmPassword, setConfirmPassword] = useState('')
const onFooterLinkPress = () => {
navigation.navigate('Login')
}
const onRegisterPress = () => {
if (password !== confirmPassword) {
alert("Passwords don't match.")
return
}
firebase
.auth()
.createUserWithEmailAndPassword(email, password)
.then((response) => {
const uid = response.user.uid
const data = {
id: uid,
email,
firstName,
lastName
};
const usersRef = firebase.firestore().collection('users')
usersRef
.doc(uid)
.set(data)
.then(() => {
navigation.navigate("Products", {user: data})
})
.catch((error) => {
alert(error)
});
})
.catch((error) => {
alert(error)
});
}
return (
<ImageBackground source={require('../../../assets/backgroundCopySilk.jpg')} style={styles.backgroundImage}>
<View style={styles.container}>
<KeyboardAwareScrollView
style={{ flex: 1, width: '100%' }}
keyboardShouldPersistTaps="always">
<Image
style={styles.logo}
source={require('../../../assets/logoCopy.png')}
/>
<TextInput
style={styles.input}
placeholder='First Name'
placeholderTextColor="#aaaaaa"
onChangeText={(text) => setFirstName(text)}
value={firstName}
underlineColorAndroid="transparent"
autoCapitalize="none"
/>
<TextInput
style={styles.input}
placeholder='Last Name'
placeholderTextColor="#aaaaaa"
onChangeText={(text) => setLastName(text)}
value={lastName}
underlineColorAndroid="transparent"
autoCapitalize="none"
/>
<TextInput
style={styles.input}
placeholder='E-mail'
placeholderTextColor="#aaaaaa"
onChangeText={(text) => setEmail(text)}
value={email}
underlineColorAndroid="transparent"
autoCapitalize="none"
/>
<TextInput
style={styles.input}
placeholderTextColor="#aaaaaa"
secureTextEntry
placeholder='Password'
onChangeText={(text) => setPassword(text)}
value={password}
underlineColorAndroid="transparent"
autoCapitalize="none"
/>
<TextInput
style={styles.input}
placeholderTextColor="#aaaaaa"
secureTextEntry
placeholder='Confirm Password'
onChangeText={(text) => setConfirmPassword(text)}
value={confirmPassword}
underlineColorAndroid="transparent"
autoCapitalize="none"
/>
<TouchableOpacity
style={styles.button}
onPress={() => onRegisterPress()}>
<Text style={styles.buttonTitle}>Create account</Text>
</TouchableOpacity>
<View style={styles.footerView}>
<Text style={styles.footerText}>Already got an account? <Text onPress={onFooterLinkPress} style={styles.footerLink}>Log in</Text></Text>
</View>
</KeyboardAwareScrollView>
</View>
</ImageBackground>
)
}
For create user You need add some Data in the method:
firebase
.auth()
.createUserWithEmailAndPassword(email, password)
.then((response) => {
const uid = response.user.uid
const data = {
id: uid,
email: useremail,
firstName: firstname,
lastName: lastname
};
const usersRef = firebase.firestore().collection('users')
usersRef
.doc(uid)
.set(data, {merge: true})
.then(() => {
navigation.navigate("Products", {user: data})
})
.catch((error) => {
alert(error)
});
})
.catch((error) => {
alert(error)
});
You make create login method where You chceck is a new user for example like this.
emailPassRegister(mail, password) {
this.afAuth.createUserWithEmailAndPassword(mail, pasword).then(ref => {
if (ref.additionalUserInfo.isNewUser) {
// method for new user
this.addNewUser(ref.user);
this.router.navigate(['/']);
} else {
// method for reapeater user
this.updataUser(ref.user);
this.router.navigate(['/']);
}
});
}
but every time if You set new data You need use {merge: true}, because if document or filed does not exist is created if exist is updated.
I hope that help You in You problem.
method to register user:
RegisterUser() {
emailPassRegister(**username from input**, **password from input**);
}