I want to read data from firebase realtime database.
I want to fix my "function readData()"
like,
If I use this funcion, I want to read my data, without enter "username".
for example, I created this,
username:hello,
email:hello#gmail.com
and If I press "read data" button, (without enter 'username')
I want to read recent data. (username and email both)
please help me!
this is my app.js
import { StatusBar } from 'expo-status-bar';
import { useState } from 'react';
import { Button, button, StyleSheet, Text, TextInput, View } from 'react-native';
import { ref, set, update, onValue, remove } from "firebase/database";
import { db } from './components/config';
export default function App() {
const [username, setName] = useState('');
const [email, setEmail] = useState('');
function createData() {
set(ref(db, 'users/' + username), {
username: username,
email: email
}).then(() => {
// Data saved successfully!
alert('data created!');
})
.catch((error) => {
// The write failed...
alert(error);
});
}
function update() {
set(ref(db, 'users/' + username), {
username: username,
email: email
}).then(() => {
// Data saved successfully!
alert('data updated!');
})
.catch((error) => {
// The write failed...
alert(error);
});
}
function readData() {
const starCountRef = ref(db, 'users/' + username);
onValue(starCountRef, (snapshot) => {
const data = snapshot.val();
setEmail(data.email);
});
}
return (
<View style={styles.container}>
<Text>firebase</Text>
<TextInput value={username} onChangeText={(username) => {setName(username)}} placeholder='Username' style={styles.TextBoxes}></TextInput>
<TextInput value={email} onChangeText={(email) => {setEmail(email)}} placeholder='Email' style={styles.TextBoxes}></TextInput>
<Button title='create data' onPress={createData}></Button>
<Button title='update data' onPress={update}></Button>
<Button title='read data' onPress={readData}></Button>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
TextBoxes: {
width:'90%',
fontSize:18,
padding:12,
backgroundColor:'grey',
marginVertical:10,
}
});
I understand you want to call last username by default if username is empty.
For this, you can define lastUserName state and call it if username is empty, for example;
const [lastUserName, setLastUserName] = useState('');
readData() ,
function readData() {
const starCountRef = ref(db, 'users/' + username !== '' ? username : lastUserName);
onValue(starCountRef, (snapshot) => {
const data = snapshot.val();
setEmail(data.email);
});
}
Then, view should be like that;
<View style={styles.container}>
<Text>firebase</Text>
<TextInput value={username}
onChangeText={(username) => {
setName(username)
setLastUserName(username) // add this line
}
}
placeholder='Username' style={styles.TextBoxes}></TextInput>
<TextInput value={email} onChangeText={(email) => {setEmail(email)}} placeholder='Email' style={styles.TextBoxes}></TextInput>
<Button title='create data' onPress={createData}></Button>
<Button title='update data' onPress={update}></Button>
<Button title='read data' onPress={readData}></Button>
</View>
Note : If you want to keep this state in global use Redux.
Note: Use localStorage if you want the application to run on the same state after closing and reopening. see: https://github.com/react-native-async-storage/async-storage
Related
How do I set state to that of my payload? I would like my global state to have the recent changes, not the payload. Please could someone explain why/how this is happening? Do I need to create another reducer/effect to set the state? I want to set this state as global within the app. I would greatly appreciate it.
I am using the following:
Firebase Firestore
Rematch for Redux
React Native
This is My debugger (image).
Result of the code below.
Here is my code:
Index.js
import { init } from '#rematch/core'
import user from './user'
const models = {
user,
}
const store = init({
models,
})
export default { getState, dispatch } = store
Model.js (User.js)
import firebase from 'firebase';
import db from '../config/firebase'
const user = {
state: {},
reducers: {
login(userData) {
return userData
},
email(state, email) {
return { ...state, email }
},
password(state, password) {
return { ...state, password }
},
username(state, username) {
return { ...state, username }
},
fullname(state, fullname) {
return { ...state, fullname }
},
},
effects: () => ({
async signup() {
const { email, password, username, fullname } = getState().user
const response = await firebase.auth().createUserWithEmailAndPassword(email, password)
if (response.user.uid) {
const userData = {
uid: response.user.uid,
email: email,
username: username,
fullname: fullname,
bio: 'test',
gender: 'teste',
phoneNum: 'teste',
profilePic: 'te',
status: 'teste',
}
db.collection('users').doc(response.user.uid).set(userData)
alert(userData.uid)
return dispatch.user.login(userData)
}
}
})
}
export default user
SignUp.js
import * as React from 'react';
import {
TextInput,
Text,
KeyboardAvoidingView,
SafeAreaView,
TouchableOpacity,
Alert,
}
from 'react-native';
import styles from '../styles'
import { connect } from 'react-redux';
import '#expo/vector-icons';
import 'redux';
class Signup extends React.Component {
onPress = () => {
this.props.SignUp()
this.props.navigation.navigate('Home')
}
render() {
const { routeName } = this.props.navigation.state
return (
<SafeAreaView style={styles.container}>
<KeyboardAvoidingView behavior='position'>
<Text style={styles.mainText}>
EMAIL
</Text>
<TextInput
style={styles.inputText}
editable={routeName === 'Signup' ? true : false}
value={this.props.user.email}
onChangeText={input => this.props.setEmail(input)}
/>
<Text style={styles.mainText}>
PASSWORD
</Text>
<TextInput
style={styles.inputText}
editable={routeName === 'Signup' ? true : false}
value={this.props.user.password}
onChangeText={input => this.props.setPassword(input)}
secureTextEntry={true}
/>
<Text style={styles.mainText}>
USERNAME
</Text>
<TextInput
style={styles.inputText}
value={this.props.user.username}
onChangeText={input => this.props.setUserName(input)}
/>
<Text style={styles.mainText}>
FULL NAME
</Text>
<TextInput
style={styles.inputText}
value={this.props.user.fullname}
onChangeText={input => this.props.setFullName(input)}
/>
<TouchableOpacity
style={styles.buttonLighGray}
onPress={() => this.onPress()}>
<Text style={styles.buttonDarkText}>
Accept & Sign Up
</Text>
</TouchableOpacity>
</KeyboardAvoidingView>
</SafeAreaView>
);
}
}
const mapState = (state) => ({
user: state.user,
})
const mapDispatch = (dispatch) => ({
setEmail: mail => dispatch.user.email(mail),
setPassword: pass => dispatch.user.password(pass),
setUserName: usern => dispatch.user.username(usern),
setFullName: fulln => dispatch.user.fullname(fulln),
SignUp: () => dispatch.user.signup(),
})
export default connect(mapState, mapDispatch)(Signup)
Screen.js
import * as React from 'react';
import {
View,
TextInput,
Alert,
Text,
KeyboardAvoidingView,
SafeAreaView,
TouchableOpacity,
}
from 'react-native';
import styles from '../styles'
import { connect } from 'react-redux';
import { Image } from 'react-native-elements';
import '#expo/vector-icons';
import 'redux';
import firebase from 'firebase'
class Screen extends React.Component {
render() {
return (
<SafeAreaView style={styles.container}>
<Text> Full Name: {this.props.user.fullName}</Text>
<Text> Email: {this.props.user.email}</Text>
<Text> username: {this.props.user.username}</Text>
<Text> bio: {this.props.user.bio}</Text>
<Text> gender: {this.props.user.gender}</Text>
<Text> phoneNum: {this.props.user.phoneNum}</Text>
<Text> profilePic: {this.props.user.profilePic}</Text>
</SafeAreaView>
);
}
}
const mapState = (state) => ({
user: state.user,
})
const mapDispatch = (dispatch) => ({
setEmail: mail => dispatch.user.email(mail),
setPassword: pass => dispatch.user.password(pass),
setUserName: usern => dispatch.user.username(usern),
setFullName: fulln => dispatch.user.fullname(fulln),
})
export default connect(mapState, mapDispatch)(Screen)
The problem is that you are returning the current state again in the login reducer. (you declared is at user data)
login(state, payload) {
return {
...state,
...payload
}
// this will take the global state and overwrite everything that is in payload (merge both objects
},
else you could just do just return payload but this could overwrite other stored values in the future!
How to delete a image in firebase storage using the url of the image in react native?
this is the structure of the data
list {
["https://firebasestorage.googleapis.com/v0/b/testes-109.appspot.com/o/photos%2FmdWs20BYhSdR4XIePdpBL9szC7i2%2F79337645-7aa6-4fa3-ab29-9dae6f41bc6?alt=media&token=a9cc2795-f118-485c-94b9-cdf0c083eb2a", "https://firebasestorage.googleapis.com/v0/b/testes-109.appspot.com/o/photos%2FmdWs20BYhSdR4XIePdpBL9szC7i2%2F79337645-7aa6-4fa3-ab29-9dabe6f41bc6?alt=media&token=a9cc2795-f118-48c-94b9-cdf0c83eb2a", ],
}
i tried this
<FlatList
data={list}
renderItem={({ item, index }) => {
return (
<View >
<TouchableOpacity onPress={() => this.deleteImage(item)} >
<Image source={{ uri: item }} style={{ width:100, height: 100 }} />
</TouchableOpacity >
</View>
)
}}
/>
deleteImage = (item) => {
alert(item)
var desertRef = item;
desertRef.delete()
.then(function() {
console.log('File deleted successfully')
}).catch(function(error) {
console.log('Uh-oh, an error occurred!')
});
}
but got this error
desertRef.delete is not a fuction. (in 'desertRef.delete()', 'desertRef.delete' is undefined
create storage object with your firebaseConfig
const app = initializeApp(firebaseConfig);
const storage = getStorage(app);
export default storage;
You need to use the following function to delete it from storage.
import { deleteObject, ref } from "firebase/storage";
import storage from "<your storage file path where you export it>";
export const deleteFromStorage = (file: string | undefined) => {
if (file) {
let pictureRef = ref(storage, file);
deleteObject(pictureRef)
.then(() => {
alert("Picture is deleted successfully!");
})
.catch((err) => {
console.log(err);
});
}
}
I have a registers and push data to Firebase function. I have a problem that when two functions are nested they are registered and stored in Firebase but there are warnings (below). But when I delete the push data function, there is no warning. I want to be able to register and be able to save data. Or can I write two separate functions and when onPress can call two functions at the same time?
This is my code:
handleSignUp = () => {
const { username, email, passwordOne } = this.state;
const { history } = this.props;
auth.doCreateUserWithEmailAndPassword(email, passwordOne)
.then(authUser => {
// Create a user in your own accessible Firebase Database too
db.doCreateUser(authUser.user.uid, username, email)
.then(() => {
this.setState({ ...INITIAL_STATE }, () => {
history.navigation.navigate("MainScreenNavigator");
});
})
.catch(error => this.setState({ errorMessage: error.message }));
})
.catch(error => this.setState({ errorMessage: error.message }));
};
And warning:
Warning: Can't call setState (or forceUpdate) on an unmounted
component. This is a no-op, but it indicates a memory leak in your
application. To fix, cancel all subscriptions and asynchronous tasks
in the componentWillUnmount method.
doCreactUser function
export const doCreateUser = (id, username, email) =>
db.ref(`users/${id}`).set({
username,
email,
});
Full code:
import React, { Component } from "react";
import {
StyleSheet,
Text,
View,
StatusBar,
TextInput,
TouchableOpacity,
KeyboardAvoidingView
} from "react-native";
import Logo from "../components/Logo";
import { Actions } from "react-native-router-flux";
import { auth, db, firebase } from "../firebase/";
const INITIAL_STATE = {
username: "",
email: "",
passwordOne: "",
passwordTwo: "",
errorMessage: null
};
export default class Signup extends Component<{}> {
constructor(props) {
super(props);
this.state = { INITIAL_STATE };
}
handleSignUp = () => {
const { username, email, passwordOne } = this.state;
const { history } = this.props;
auth.doCreateUserWithEmailAndPassword(email, passwordOne)
.then(authUser => {
// Create a user in your own accessible Firebase Database too
db.doCreateUser(authUser.user.uid, username, email)
.then(() => {
this.setState({ ...INITIAL_STATE }, () => {
history.navigation.navigate("MainScreenNavigator");
});
})
.catch(error => this.setState({ errorMessage: error.message }));
})
.catch(error => this.setState({ errorMessage: error.message }));
};
goBack() {
Actions.pop();
}
render() {
const {
username,
email,
passwordOne,
passwordTwo,
} = this.state;
const isInvalid =
passwordOne !== passwordTwo ||
passwordOne === "" ||
email === "" ||
username === "";
const display = isInvalid ? "none" : "flex";
return (
<View style={styles.container}>
<StatusBar backgroundColor="#99d066" barStyle="light-content" />
<Logo />
<KeyboardAvoidingView>
<TextInput
style={styles.inputBox}
underlineColorAndroid="rgba(0,0,0,0)"
placeholder="Full Name"
placeholderTextColor="#000"
autoCapitalize="none"
selectionColor="#fff"
keyboardType="default"
onSubmitEditing={() => this.passwordOne.focus()}
onChangeText={username => this.setState({ username })}
value={this.state.username}
/>
<TextInput
style={styles.inputBox}
underlineColorAndroid="rgba(0,0,0,0)"
placeholder="Email"
placeholderTextColor="#000"
autoCapitalize="none"
selectionColor="#fff"
keyboardType="email-address"
onSubmitEditing={() => this.passwordOne.focus()}
onChangeText={email => this.setState({ email })}
value={this.state.email}
/>
<TextInput
style={styles.inputBox}
underlineColorAndroid="rgba(0,0,0,0)"
placeholder="Password"
secureTextEntry={true}
placeholderTextColor="#000"
autoCapitalize="none"
ref={input => (this.passwordOne = input)}
onChangeText={passwordOne => this.setState({ passwordOne })}
value={this.state.passwordOne}
/>
<TextInput
style={styles.inputBox}
underlineColorAndroid="rgba(0,0,0,0)"
placeholder="Confirm Password"
secureTextEntry={true}
placeholderTextColor="#000"
autoCapitalize="none"
ref={input => (this.passwordTwo = input)}
onChangeText={passwordTwo => this.setState({ passwordTwo })}
value={this.state.passwordTwo}
/>
</KeyboardAvoidingView>
<TouchableOpacity style={[styles.button, { display }]}>
<Text style={styles.buttonText} onPress={this.handleSignUp}>
Sign up
</Text>
</TouchableOpacity>
{this.state.errorMessage && (
<Text style={{ color: "#b71c1c", textAlign: "center" }}>
{this.state.errorMessage}
</Text>
)}
<View style={styles.signupTextCont}>
<Text style={styles.signupText}>Already have an account?</Text>
<TouchableOpacity onPress={this.goBack}>
<Text
style={styles.signupButton}
onPress={() => this.props.navigation.navigate("Login")}
>
{" "}
Sign in
</Text>
</TouchableOpacity>
</View>
</View>
);
}
}
const styles = StyleSheet.create({...});
App loads and Authentication form shows
android emulator showing error
Hi , so i'm a newbie to React and i'm following this Udemy course .. when i try to run, my app is loaded and it renders the Authentication form like a charm with no errors or warnings.
but once i try to sign in , once i hit the Login button : the scary Red Screen pops up .
i went through all the similar subjects , but none of them seem to fix my error .. i cant even get what exactly is wrong here
Here's my LoginForm.js :
import { connect } from 'react-redux';
import React, { Component } from 'react';
import { Card, CardSection, Input, Button } from './common';
import { emailChanged, passwordChanged, loginUser } from '../actions';
class LoginForm extends Component {
onEmailChange(text) {
this.props.emailChanged(text);
}
onPasswordChange(text) {
this.props.passwordChanged(text);
}
onButtonPress() {
const { email, password } = this.props;
this.props.loginUser({ email, password });
}
render() {
return (
<Card>
<CardSection>
<Input
label="Email"
placeholder="votre email ici"
onChangeText={this.onEmailChange.bind(this)}
value={this.props.email}
/>
</CardSection>
<CardSection>
<Input
secureTextEntry
label="mot de passe"
placeholder="mot de passe"
onChangeText={this.onPasswordChange.bind(this)}
value={this.props.password}
/>
</CardSection>
<CardSection>
<Button onPress={this.onButtonPress.bind(this)}>
Login
</Button>
</CardSection>
</Card>
);
}
}
const mapStateToProps = (state) => {
return {
email: state.auth.email,
password: state.auth.password
};
};
export default connect(mapStateToProps, { emailChanged, passwordChanged,
loginUser })(LoginForm);
Here's my actions creator :
import firebase from 'firebase';
import {
EMAIL_CHANGED,
PASSWORD_CHANGED,
LOGIN_USER_SUCCESS
} from './types';
export const emailChanged = (text) => {
return {
type: EMAIL_CHANGED,
paymoad: text
};
};
export const passwordChanged = (text) => {
return {
type: PASSWORD_CHANGED,
payload: text
};
};
export const loginUser = ({ email, password }) => {
return (dispatch) => {
firebase.auth().signInWithEmailAndPassword(email, password)
.then(user => {
dispatch({ type: LOGIN_USER_SUCCESS, payload: user });
});
};
};
In the emailChanged action, you are using the wrong key for the payload. Instead of using payload you are using paymoad
With this you are not updating the store and the value for the email is not valid.
I'm recently practicing React Native with Redux and developing a login form attached to Firebase. The thing is, whenever the signin button is clicked it should give an error above button "authentication failed".
But whenever I tried to click the button, it gives an error: "signinwithemailandpassword failed first argument email must be a valid string".
I've tried hours to solve this but couldn't get the answer.
Here is my code:
LOGINFORM:
import React, { Component } from 'react';
import { View, Text } from 'react-native';
import { CardSection, Card, Input, Button } from './common';
import { emailChanged, passwordChanged, loginUser } from '../actions';
import { connect } from 'react-redux';
class LoginForm extends Component {
onEmailChange(text) {
this.props.emailChanged(text);
//Its like setState to action, the text is send as a parameter to our action.
}
onPasswordChange(text){
this.props.passwordChanged(text);
}
onButtonPress(){
this.props.loginUser( this.props.email, this.props.password );
}
renderError(){
if (this.props.error){
<View style={{ backgroundColor: 'white' }}>
<Text style={ Styles.errorTextStyle }>
{this.props.error}
</Text>
</View>
}
}
render() {
return(
<Card>
<CardSection>
<Input
label='Email'
placeHolder='email#gmail.com'
onChangeText={this.onEmailChange.bind(this)}
value={this.props.email}
//What is this function bind to?
//Actually, this bind function has a 'this' keyword and 'this' keyword is actually a
//parameter that is send to the onEmailChange, 'this' is recieved by 'text' param as the
//text written in the email field so its binded and called whenever user writes anything
//in the field of email.
//We're using 'this' onEmailChange is a call me back (callback) function that will invoke
//when input is pressed or not pressed, that is why we're using bind.
/>
</CardSection>
<CardSection>
<Input
secureTextEntry
label='Password'
placeHolder='password'
onChangeText={this.onPasswordChange.bind(this)}
value={this.props.password}
/>
</CardSection>
{this.renderError()}
<CardSection>
<Button onPress={this.onButtonPress.bind(this)}> Login </Button>
</CardSection>
</Card>
);
}
}
const Styles = {
errorTextStyle: {
fontSize: 20,
alignSelf: 'center',
color: 'red'
}
}
const mapStateToProps = (state) => {
return {
email: state.auth.email,
password: state.auth.password,
error: state.auth.error
};
console.log(state.auth.email);
};
export default connect(mapStateToProps, { emailChanged, passwordChanged, loginUser })(LoginForm);
//since we connect and added { emailChanged } as action, now we can access this.props.emailChanged.
ACTION INDEX FILE:
import firebase from 'firebase';
import { EMAIL_CHANGED, PASSWORD_CHANGED, LOGIN_USER_SUCCESS, LOGIN_USER_FAIL } from './types';
export const emailChanged = (text) => {
return{
type: EMAIL_CHANGED,
payload: text
};
}
export const passwordChanged = (text) => {
return {
type: PASSWORD_CHANGED,
payload: text
};
}
export const loginUser = ({ email, password }) => {
return(dispatch) => {
firebase.auth().signInWithEmailAndPassword(email, password)
.then(user => loginUserSuccess(dispatch, user))
.catch(() => {
firebase.auth().createUserWithEmailAndPassword(email, password)
.then(user => loginUserSuccess(dispatch, user))
.catch(() => loginUserFail(dispatch));
});
};
};
const loginUserFail = (dispatch) => {
dispatch({ type: LOGIN_USER_FAIL });
};
const loginUserSuccess = (dispatch, user) => {
dispatch({ type: LOGIN_USER_SUCCESS, payload: user });
};
AUTH REDUCER:
import { EMAIL_CHANGED, PASSWORD_CHANGED, LOGIN_USER_SUCCESS, LOGIN_USER_FAIL } from '../actions/types';
const INITIAL_STATE = { email: '', password: '', user: null, error: '' };
export default (state = INITIAL_STATE, action) => {
//switch statement in Reducer
switch (action.type) {
case EMAIL_CHANGED:
return { ...state, email: action.payload };
case PASSWORD_CHANGED:
return { ...state, password: action.payload };
case LOGIN_USER_SUCCESS:
return { ...state, user: action.payload };
case LOGIN_USER_FAIL:
return { ...state, error: 'Authentication failed.' };
default:
return state;
}
};
APP.JS
import React, {Component} from 'react';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import firebase from 'firebase';
import ReduxThunk from 'redux-thunk';
import reducers from './reducers';
import LoginForm from './components/LoginForm'
class App extends Component {
componentWillMount() {
var config = {
apiKey: 'AIzaSyAjHwCvftP1w0nKJTylUQcXAH-rThhZ6sQ',
authDomain: 'bold-circuit-429.firebaseapp.com',
databaseURL: 'https://bold-circuit-429.firebaseio.com',
projectId: 'bold-circuit-429',
storageBucket: 'bold-circuit-429.appspot.com',
messagingSenderId: '270696683683'
};
firebase.initializeApp(config);
}
render(){
const store = createStore(reducers, {}, applyMiddleware(ReduxThunk));
return(
<Provider store={store}>
<LoginForm />
</Provider>
);
}
}
export default App;
It looks like the problem is your connect() function call in LOGINFORM.
I pull out your { emailChanged, passwordChanged, loginUser } argument you're passing to connect() and change it to this:
const mapStateToProps = (state) => {
return {
email: state.auth.email,
password: state.auth.password,
error: state.auth.error
};
console.log(state.auth.email);
};
const mapDispatchToProps = (dispatch) => {
return {
emailChanged: (emailAddress) => dispatch(emailChanged(emailAddress),
passwordChanged: (password) => dispatch(passwordChanged(password)),
loginUser: (email, password) => dispatch(loginUser(email, password))
}
};
export default connect(mapStateToProps, mapDispatchToProps)(LoginForm);
Your initial attempt used object decomposition to create an object to pass to connect. That object ended up looking like
{
emailChanged: emailChanged,
passwordChanged: passwordChanged,
loginUser: loginUser
}
My function will take a dispatch argument and map those three values of props (emailChanged, passwordChanged, loginUser) to functions that dispatch the action to your reducers.
EDIT: Your full LOGINFORM.js file should look like this:
import React, { Component } from 'react';
import { View, Text } from 'react-native';
import { CardSection, Card, Input, Button } from './common';
import { emailChanged, passwordChanged, loginUser } from '../actions';
import { connect } from 'react-redux';
class LoginForm extends Component {
onEmailChange(text) {
this.props.emailChanged(text);
//Its like setState to action, the text is send as a parameter to our action.
}
onPasswordChange(text){
this.props.passwordChanged(text);
}
onButtonPress(){
this.props.loginUser( this.props.email, this.props.password );
}
renderError(){
if (this.props.error){
<View style={{ backgroundColor: 'white' }}>
<Text style={ Styles.errorTextStyle }>
{this.props.error}
</Text>
</View>
}
}
render() {
return(
<Card>
<CardSection>
<Input
label='Email'
placeHolder='email#gmail.com'
onChangeText={this.onEmailChange.bind(this)}
value={this.props.email}
//What is this function bind to?
//Actually, this bind function has a 'this' keyword and 'this' keyword is actually a
//parameter that is send to the onEmailChange, 'this' is recieved by 'text' param as the
//text written in the email field so its binded and called whenever user writes anything
//in the field of email.
//We're using 'this' onEmailChange is a call me back (callback) function that will invoke
//when input is pressed or not pressed, that is why we're using bind.
/>
</CardSection>
<CardSection>
<Input
secureTextEntry
label='Password'
placeHolder='password'
onChangeText={this.onPasswordChange.bind(this)}
value={this.props.password}
/>
</CardSection>
{this.renderError()}
<CardSection>
<Button onPress={this.onButtonPress.bind(this)}> Login </Button>
</CardSection>
</Card>
);
}
}
const Styles = {
errorTextStyle: {
fontSize: 20,
alignSelf: 'center',
color: 'red'
}
}
const mapStateToProps = (state) => {
return {
email: state.auth.email,
password: state.auth.password,
error: state.auth.error
};
console.log(state.auth.email);
};
const mapDispatchToProps = (dispatch) => {
return {
emailChanged: (emailAddress) => dispatch(emailChanged(emailAddress),
passwordChanged: (password) => dispatch(passwordChanged(password)),
loginUser: (email, password) => dispatch(loginUser(email, password))
}
};
export default connect(mapStateToProps, mapDispatchToProps)(LoginForm);
//since we connect and added { emailChanged } as action, now we can access this.props.emailChanged.
onButtonPress(){
this.props.loginUser( this.props.email, this.props.password );
}
wrong call LoginUser function
onButtonPress(){
this.props.loginUser({ this.props.email, this.props.password });
}