React-native firebase Signinwithemal and createuserwithemailandpassword - firebase

i am trying to make a simple login app, when you try to login with an account that isnt registered, it should just make a new account.
Like you can see on my onButtonPress function, my problem is that whatever i try to fill in, i get the error message. Which doesnt make sense, normally if i would fill in an email-adres and password for the first time, it should just register me, but instead of that, i just always get the error message.
Here you can see my LoginForm class
import React, { Component } from 'react';
import { Text } from 'react-native';
import firebase from 'firebase';
import { Button, Card, CardSection, Input } from './common';
class LoginForm extends Component {
state = { email: '', password: '', error: '' };
onButtonPress() {
const { email, password } = this.state;
firebase.auth().signInWithEmailAndPassword(email, password)
.catch(() => {
firebase.auth().createUserWithEmailAndPassword(email, password)
.catch(() => {
this.setState({ error: 'Authentication failed' });
});
});
}
render() {
return (
<Card>
<CardSection>
<Input
placeholder="user#gmail.com"
label="Email"
value={this.state.email}
onChangeText={email => this.setState({ email })}
/>
</CardSection>
<CardSection>
<Input
secureTextEntry
placeholder="password"
label="Password"
value={this.state.password}
onChangeText={password => this.setState({ password })}
/>
</CardSection>
<Text style={styles.errorTextStyle}>
{this.state.error}
</Text>
<CardSection>
<Button onPress={this.onButtonPress.bind(this)}>
Log in
</Button>
</CardSection>
</Card>
);
}
}
const styles = {
errorTextStyle: {
fontSize: 20,
alignSelf: 'center',
color: 'red'
}
};
export default LoginForm;
I will add my Input class as well, you never know what could be wrong... :)
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
placeholder={placeholder}
autoCorrect={false}
secureTextEntry={secureTextEntry}
style={inputStyle}
value={value}
onChangeText={onChangeText}
/>
</View>
);
};
const styles = {
inputStyle: {
color: '#000',
paddingRight: 5,
paddingLeft: 5,
fontSize: 18,
lineHeight: 23,
flex: 2,
height: 40
},
labelStyle: {
fontSize: 18,
paddingLeft: 20,
flex: 1
},
containerStyle: {
height: 40,
flex: 1,
flexDirection: 'row',
alignItems: 'center'
}
};
export { Input };

You do not have a .then(), only a .catch(). Maybe this can help?
firebase.auth().createUserWithEmailAndPassword(email, password).then()

Related

Testing React Native with Jest - Doesn't test 'onPress' and 'onChangeText'

I'm testing a component called ForgotPasswordComponent in React Native with Jest. The code for the component is seen here:
import { StyleSheet, View, ToastAndroid, Dimensions } from 'react-native'
import React, {useState} from 'react'
import {Button, Headline, Text, TextInput} from 'react-native-paper';
import { getAuth, sendPasswordResetEmail } from "firebase/auth";
import { useNavigation } from '#react-navigation/native';
import { ScaledSheet } from 'react-native-size-matters';
const {height, width} = Dimensions.get('window')
export default function ForgotPasswordComponent() {
const [email, setEmail] = useState('');
const auth = getAuth();
const navigation = useNavigation();
const forgotPassword = () => {
sendPasswordResetEmail(auth, email)
.then(() => {
ToastAndroid.show('Reset password mail sent successfully!', ToastAndroid.LONG);
})
.catch(() => {
ToastAndroid.show('Error: Please check your entered e-mail!', ToastAndroid.LONG)
});
}
return (
<View style={styles.container}>
<View>
<Button style={styles.buttonBack} uppercase={false} onPress={() => {navigation.navigate("Login")}}>
<Text style={styles.buttonTextGoBack}>Go back</Text>
</Button>
</View>
<View>
<Headline style={styles.headline}>Forgot your password? No problem!</Headline>
</View>
<View>
<Text style={styles.inputText}>Email:</Text>
<TextInput style={styles.input} placeholder="Enter your email" value={email} onChangeText={text => setEmail(text)}></TextInput>
</View>
<View>
<Button style={styles.buttonResetPassword} mode="contained" uppercase={false} onPress={forgotPassword}>
<Text style={styles.buttonTextResetPassword}>Reset password</Text>
</Button>
</View>
</View>
)
}
const styles = ScaledSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
marginBottom: '200#s'
},
headline: {
fontSize: '18#s',
marginTop: '60#s',
padding: '20#s',
},
inputText: {
paddingLeft: '14#s',
paddingTop: '6#s',
fontSize: '14#s'
},
input: {
padding: '10#s',
margin: '15#s',
width: width * 0.8,
height: height * 0.03,
fontSize: '14#s'
},
buttonResetPassword: {
width: width * 0.5,
},
buttonBack: {
paddingRight: '260#s',
width: width * 1.1,
},
buttonTextResetPassword: {
color: 'white',
fontSize: '14#s'
},
buttonTextGoBack: {
fontSize: '14#s'
}
})
As it is seen, it uses two functions from Firebase and the component have very little functionality.
Here is the testcases that I have wrote so far:
import React from 'react';
import renderer from 'react-test-renderer'
import ForgotPasswordComponent from '../components/ForgotPassword/ForgotPasswordComponent';
import { NavigationContainer } from '#react-navigation/native';
import { fireEvent, render } from '#testing-library/react-native';
import { Button, TextInput } from 'react-native-paper';
jest.useFakeTimers()
jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper');
const mockGetAuth = jest.fn()
const mockSendPassword = jest.fn(() => {
return Promise.resolve(true)
})
jest.mock('firebase/auth', () => {
return {
getAuth: () => mockGetAuth,
sendPasswordResetEmail: () => mockSendPassword
}
})
//Testing that navigation is working
describe("Navigation working", () => {
it("calls useNavigation and navigates", () => {
const mockedNavigate = jest.fn();
jest.mock('#react-navigation/native', () => (
{ useNavigation: () => ({ navigate: mockedNavigate }) }));
const onPress = jest.fn(mockedNavigate);
const {getByText} = render(
<Button onPress={onPress}>Go Back</Button>,
);
fireEvent.press(getByText('Go Back'));
expect(mockedNavigate).toBeCalledTimes(1);
})
})
//Testing buttons and inputfield are working
describe('Buttons and input on press working', () => {
it('Go back onpress is called', () => {
const onPress = jest.fn();
const {getByText} = render(
<Button onPress={onPress}>Go Back</Button>,
);
fireEvent.press(getByText('Go Back'));
expect(onPress).toBeCalledTimes(1);
});
it('Reset onpress is called', () => {
const onPress = jest.fn();
const {getByText} = render(
<Button onPress={onPress}>Reset password</Button>,
)
fireEvent.press(getByText('Reset password'));
expect(onPress).toBeCalledTimes(1);
})
it('Email onChange is called', () => {
const onChangeTextMock = jest.fn();
const {getByPlaceholderText} = render(
<TextInput placeholder="Enter your email" onChangeText={onChangeTextMock}/>
);
fireEvent.changeText(getByPlaceholderText("Enter your email"), "test#gmail.com");
expect(onChangeTextMock).toBeCalled();
})
});
//Snapshot testing
test('renders forgotPasswordComponent correctly 1', () => {
const tree = renderer.create(
<NavigationContainer>
<ForgotPasswordComponent/>
</NavigationContainer>)
.toJSON();
expect(tree).toMatchSnapshot();
});
All the testcases runs succesfully, but when I inspect the code coverage I don't understand why my onPress function on line 30 and onChangeText function on line 39 are red. It is like they are not getting tested at all despite I have made testcases for them.
Besides are there any solution of how I can test the Firebase function sendPasswordResetEmail is called when the button is pressed and it shows the succesfully toast-message?

Problem in my react native project firebase module is not recognized

i installed firebase to my project folder and i can see it in node modules folder, but still when i try import firebase from 'firebase' nothing happens
i don't know why i uninstalled it and re installed it
i searched for this problem but with no solution to found it like firebase module does not exist at all
i even restarted my computer
i cannot even intializeApp
i have tried to change my import line too
import React from 'react'
import {
View,
Button,
TextInput,
StyleSheet,
Image,
} from 'react-native'
// import firebase from 'firebase';
import * as firebase from 'firebase'
const firebaseConfig={
apiKey: "AIzaSyCDh998mIGLdyHaE3EK5tRnhLY-I7jiPOY",
authDomain: "shiftorgnaizer.firebaseapp.com",
databaseURL: "https://shiftorgnaizer.firebaseio.com",
projectId: "shiftorgnaizer",
storageBucket: ""
};
export default class SignUp extends React.Component {
state = {
username: '', password: '', email: '', phone_number: ''
}
onChangeText = (key, val) => {
this.setState({ [key]: val })
}
signUp = async () => {
const { username, password, email, phone_number } = this.state
}
render() {
return (
<View style={styles.container}>
<Image source={require('./Images/allImages.jpg')}
style={{width: 150,height: 100}}/>
<TextInput
style={styles.input}
placeholder='Username'
autoCapitalize="none"
placeholderTextColor='white'
onChangeText={val => this.onChangeText('username', val)}
/>
<TextInput
style={styles.input}
placeholder='Password'
secureTextEntry={true}
autoCapitalize="none"
placeholderTextColor='white'
onChangeText={val => this.onChangeText('password', val)}
/>
<TextInput
style={styles.input}
placeholder='Email'
autoCapitalize="none"
placeholderTextColor='white'
onChangeText={val => this.onChangeText('email', val)}
/>
<TextInput
style={styles.input}
placeholder='Phone Number'
autoCapitalize="none"
placeholderTextColor='white'
onChangeText={val => this.onChangeText('phone_number', val)}
/>
<Button
title='Sign Up'
onPress={this.signUp}
/>
</View>
)
}
}
const styles = StyleSheet.create({
input: {
width: 350,
height: 55,
backgroundColor: '#42A5F5',
margin: 10,
padding: 8,
color: 'white',
borderRadius: 14,
fontSize: 18,
fontWeight: '500',
},
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}
})
expected to recognize the module and work with firebase

How to debug "undefined is not an object" when navigating between screens

I'm trying when I press Login button to go to Drawer screen which contains all my other screens but I'm getting the following error:
TypeError: undefined is not an object (evaluating
'this.props.navigation.navigate')
Here is my DrawerScreen:
import React, {Component} from 'react';
import { Button, View, Text, Dimensions, ImageBackground } from 'react-native';
import { createStackNavigator, createAppContainer, createDrawerNavigator, DrawerItems } from 'react-navigation';
import HomeScreen from './HomeScreen';
import AboutScreen from './AboutScreen';
import Count from './CountScreen';
const DrawerContent = (props) => (
<View>
<ImageBackground
source={{uri:'https://cdn.pixabay.com/photo/2017/12/13/07/15/natural-3016177_960_720.jpg'}}
style={{}}
imageStyle= {{opacity: 0.7}}
>
<View
style={{
//backgroundColor: '#73a2ef',
height: 140,
alignItems: 'center',
justifyContent: 'center',
}}
>
<Text style={{ color: 'black', fontSize: 40, fontWeight: 'bold' }}>
Menu
</Text>
</View>
</ImageBackground>
<DrawerItems {...props} />
</View>
)
const WIDTF = Dimensions.get('window').width;
const DrawerConfig = {
drawerWidth: WIDTF*0.80,
drawertType: 'back',
}
const Drawer = createDrawerNavigator ({
Home: {
screen: HomeScreen
},
About: {
screen: AboutScreen
},
Count: {
screen: Count
},
},
{
drawerBackgroundColor: '#c7d1a7',
contentComponent: DrawerContent,
contentOptions: {
activeTintColor: 'blue',
style: {
flex: 1,
paddingTop: 15,
}
}},
DrawerConfig
);
const AppContainer = createAppContainer(Drawer);
export default AppContainer;
And here is my LogInScreen:
import React, {Component} from 'react';
import * as firebase from 'firebase';
import {Container, Content, Header, Form, Input, Item, Button, Label, Drawer} from 'native-base';
import {StyleSheet, Text} from 'react-native';
import AppContainer from './DrawerNavigatorNew';
const firebaseConfig = {
apiKey:
authDomain:
databaseURL:
projectId:
storageBucket:
};
firebase.initializeApp(firebaseConfig);
export default class LoginScreen extends React.Component {
constructor (props) {
super(props)
this.state =({
email:'',
password:'',
})
}
signUpUser = (email, password) => {
try {
if(this.state.password.length <6)
{
alert("Please enter atleast 6 characters")
return;
}
firebase.auth().createUserWithEmailAndPassword(email, password)
}
catch (error){
console.log(error.toString())
}
}
loginUser =(email, password) => {
try{
firebase.auth().signInWithEmailAndPassword(email, password).then(function(user){
console.log(user)
})
}
catch (error) {
console.log(error.toString())
}
}
render() {
const {navigate} = this.props.navigation;
return (
<Container style={styles.container}>
<Form>
<Item floatingLabel>
<Label> Email </Label>
<Input
name='email'
autoCorrect={false}
autoCapitalize='none'
onChangeText={(email)=> this.setState({email})}
/>
</Item>
<Item floatingLabel>
<Label> Password </Label>
<Input
name='password'
secureTextEntry={true}
autoCorrect={false}
autoCapitalize='none'
onChangeText={(password)=> this.setState({password})}
/>
</Item>
<Button style={{marginTop: 10}}
full
rounded
success
onPress = {()=> this.loginUser(this.state.email,this.state.password) || navigate(AppContainer)}
>
<Text> Login </Text>
</Button>
<Button style={{marginTop: 10}}
full
rounded
primary
onPress = {()=> this.signUpUser(this.state.email,this.state.password)}
>
<Text style={{color: 'white' }}> Sign Up </Text>
</Button>
</Form>
</Container>
);
}
}
const styles = StyleSheet.create ({
container:{
flex: 1,
backgroundColor: 'white',
justifyContent: 'center',
padding: 10
}
})
And the Error:
I misread the code. 'Navigate' is a command to move the screen. The 'createDrawenavigator' must open the drawer.
Can you try this Code?
onPress = {()=> this.loginUser(this.state.email,this.state.password) || this.props.navigation.openDrawer();}
Change the Navigator configuration if you want to move the screen.
createStackNavigator({
A: {
screen: AScreen,
navigationOptions: () => ({
title: `A`,
headerBackTitle: 'A much too long text for back button from B to A',
headerTruncatedBackTitle: `to A`
}),
},
B: {
screen: BScreen,
navigationOptions: () => ({
title: `B`,
}),
}
});

Logout Button not appearing After login?

I setup firebase authentication for my react native application. I was able to create new login and authentication failure for any incorrect login .
Once the user is login , i want them to logout using a button but unfortunately the button is not visible and only the text is appearing on screen ..
“ App.js “
import React, { Component } from 'react';
import { View } from 'react-native';
import firebase from 'firebase';
import { Header, Button, Spinner } from './components/common';
import LoginForm from './components/LoginForm';
class App extends Component {
state = { loggedIn: null };
componentWillMount() {
firebase.initializeApp(
{
apiKey: "",
authDomain: "",
databaseURL: "",
projectId: "",
storageBucket: "",
messagingSenderId: ""
}
);
firebase.auth().onAuthStateChanged((user) => {
if (user) {
this.setState({ loggedIn: true });
} else {
this.setState({ loggedIn: false });
}
});
}
renderContent() {
switch (this.state.loggedIn) {
case true:
return (
<Button onPress={() => firebase.auth().signOut()}>
Log Out
</Button>
);
case false:
return <LoginForm />;
default:
return <Spinner size="large" />;
}
}
render() {
return (
<View>
<Header headerText="Authentication" />
{this.renderContent()}
</View>
);
}
}
export default App;
"Button.js"
import React from 'react';
import { Text, TouchableOpacity } from 'react-native';
const Button = ({ onPress, children }) => {
const { buttonStyle, textStyle } = styles;
return (
<TouchableOpacity onPress={onPress} style={buttonStyle}>
<Text style={textStyle}>
{children}
</Text>
</TouchableOpacity>
);
};
const styles = {
textStyle: {
alignSelf: 'center',
color: '#007aff',
fontSize: 16,
fontWeight: '600',
paddingTop: 10,
paddingBottom: 10
},
buttonStyle: {
flex: 1,
alignSelf: 'stretch',
backgroundColor: '#fff',
borderRadius: 5,
borderWidth: 1,
borderColor: '#007aff',
marginLeft: 5,
marginRight: 5
}
};
export { Button };
Thanks in advance.
edit your button like this
<Button children="Log Out" onPress={() => firebase.auth().signOut()}>
</Button>

React Native: Object is not a function

I am working with Firebase authentification in my React Native android app, however every time I try to login and press the button, it gives me this error:
Object is not a function(evaluating 'this2.state'({
error: 'Authentification failed', loading: false
}))
I have looked up similar answers as well, but it doesn't seem to match my problem. Any help would be appreciated.
Here is my code:
import React from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
PixelRatio,
TouchableOpacity,
Image,
Button,
} from 'react-native';
import * as firebase from 'firebase';
import { FormLabel, FormInput } from 'react-native-elements';
import Help from './app/components/Help';
import { Input } from './app/components/Input';
const util = require('util');
firebase.initializeApp({
apiKey: 'AIzaSyCmjeFuDoMeOkeG5J-TCXzDJ1vtaDqUXjE',
authDomain: 'dev-pre-do.firebaseapp.com',
databaseURL: 'https://dev-pre-do.firebaseio.com',
projectId: 'dev-pre-do',
storageBucket: 'dev-pre-do.appspot.com',
messagingSenderId: '943752089124'
}
);
class LoginScreen extends React.Component {
static navigationOptions ={
header: null,
};
constructor(props) {
super(props);
this.state = {email:'', password:'', error: '', loading:false};
}
onLoginPress(){
this.setState({error:'', loading:true});
const{email, password} = this.state;
firebase.auth().signInWithEmailAndPassword(email, password)
.then(() => {
this.state({error: '', loading: false});
this.props.navigation.navigate('CreateIdeaMenu');
})
.catch(() => {
this.state({error: 'Authentification failed', loading: false});
})
}
renderButtonOrLoading(){
if(this.state.loading) {
return (
<Text style={styles.loading}> Loading </Text>
)}
return (
<View>
<Button style={styles.Button} title='Login'
onPress={this.onLoginPress.bind(this)}></Button>
</View>
)
}
render() {
return (
<View style={styles.container}>
<Help onPress = {()=> navigate("HelpFirst")}/>
<Image style={styles.logo}
source={require('./app/images/PREDO_logo_white.png')}
/>
<FormLabel> Email</FormLabel>
<FormInput onChangeText={email => this.setState({ email })}/>
<FormLabel> Password</FormLabel>
<FormInput onChangeText={password => this.setState({ password })}/>
<Text>{this.state.error}</Text>
{/* <Input
placeholder='Email'
label='Email'
onChangeText={email => this.setState({ email })}
value={this.state.email}
/>
<Input
placeholder='Password'
label='Password'
secureTextEntry
onChangeText={password => this.setState({ password })}
value={this.state.password} */}
{this.renderButtonOrLoading()}
{/* <Button onPress={() => console.log('pressed')}>Log in</Button>*/}
{/* <RegForm onPress = {()=> navigate("CreateIdeaMenu")} /> */}
</View>
);
}
};
const styles = StyleSheet.create({
container: {
flex:1,
justifyContent: 'flex-start',
alignItems: 'center',
backgroundColor: '#1e1f20',
paddingLeft: 60,
paddingRight: 60,
paddingTop: 10,
},
Button: {
width: 200,
height:100,
marginBottom: 10,
backgroundColor: 'purple',
alignItems: 'center',
justifyContent: 'center',
},
logo: {
width: 360,
height:94,
marginBottom: 80,
marginTop: 20,
},
loading: {
color: 'white',
fontSize: 50,
}
});
export default LoginScreen;
Update your code as below:
onLoginPress(){
this.setState({error:'', loading:true});
const{email, password} = this.state;
firebase.auth().signInWithEmailAndPassword(email, password)
.then(() => {
this.setState({error: '', loading: false});
this.props.navigation.navigate('CreateIdeaMenu');
})
.catch(() => {
this.setState({error: 'Authentification failed', loading: false});
})
}

Resources