Stack navigator giving me undefined error - javascript

I'm using https://facebook.github.io/react-native/docs/navigation.html by the way.
I'm trying to use the StackNavigator to go from Login.js to AboutDendro.js. What's wrong in my <Button/> component that's throwing that error in my iOS simulator?
Here's Login.js:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { ScrollView, Text, TextInput, View, Button, StyleSheet } from 'react-native';
import { login } from '../redux/actions/auth';
import {AuthenticationDetails, CognitoUser, CognitoUserAttribute, CognitoUserPool} from '../lib/aws-cognito-identity';
import StackNavigator from 'react-navigation';
import AboutDendro from './AboutDendro';
const awsCognitoSettings = {
UserPoolId: 'something',
ClientId: 'something'
};
class Login extends Component {
constructor (props) {
super(props);
this.state = {
page: 'Login',
username: '',
password: ''
};
}
get alt () { return (this.state.page === 'Login') ? 'SignUp' : 'Login'; }
handleClick (e) {
e.preventDefault();
const userPool = new CognitoUserPool(awsCognitoSettings);
// Sign up
if (this.state.page === 'SignUp') {
const attributeList = [
new CognitoUserAttribute({ Name: 'email', Value: this.state.username })
];
userPool.signUp(
this.state.username,
this.state.password,
attributeList,
null,
(err, result) => {
if (err) {
alert(err);
this.setState({ username: '', password: '' });
return;
}
console.log(`result = ${JSON.stringify(result)}`);
this.props.onLogin(this.state.username, this.state.password);
}
);
} else {
const authDetails = new AuthenticationDetails({
Username: this.state.username,
Password: this.state.password
});
const cognitoUser = new CognitoUser({
Username: this.state.username,
Pool: userPool
});
cognitoUser.authenticateUser(authDetails, {
onSuccess: (result) => {
console.log(`access token = ${result.getAccessToken().getJwtToken()}`);
this.props.onLogin(this.state.username, this.state.password);
},
onFailure: (err) => {
alert(err);
this.setState({ username: '', password: '' });
return;
}
});
}
}
togglePage (e) {
this.setState({ page: this.alt });
e.preventDefault();
}
static navigationOptions = {
title: 'AboutDendro',
};
render() {
const { navigate } = this.props.navigation;
const App = StackNavigator({
Home: { screen: Login },
Profile: { screen: AboutDendro },
});
return (
<ScrollView style={{padding: 20}}>
<Button
title="Go to Jane's profile"
onPress={() =>
navigate('AboutDendro', { name: 'AboutDendro' })
}
/>
<Text style={{fontSize: 27}}>{this.state.page}</Text>
<TextInput
placeholder='Email Address'
autoCapitalize='none'
autoCorrect={false}
autoFocus={true}
keyboardType='email-address'
value={this.state.username}
onChangeText={(text) => this.setState({ username: text })} />
<TextInput
placeholder='Password'
autoCapitalize='none'
autoCorrect={false}
secureTextEntry={true}
value={this.state.password}
onChangeText={(text) => this.setState({ password: text })} />
<View style={{margin: 7}}/>
<Button onPress={(e) => this.handleClick(e)} title={this.state.page}/>
<View style={styles.firstView}>
<Text onPress={(e) => this.togglePage(e)} style={styles.buttons}>
{this.alt}
</Text>
</View>
</ScrollView>
);
}
}
const styles = StyleSheet.create({
buttons: {
fontSize: 12,
color: 'blue',
flex: 1
},
firstView: {
margin: 7,
flexDirection: 'row',
justifyContent: 'center'
}
});
const mapStateToProps = (state, ownProps) => {
return {
isLoggedIn: state.auth.isLoggedIn
};
}
const mapDispatchToProps = (dispatch) => {
return {
onLogin: (username, password) => { dispatch(login(username, password)); }
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Login);

It is because navigation is not in your props. It is a part of your App component you created. But you do nothing with this component.
You should have an App.js file, with your stackNavigator, set your Login component as your default component in your stackNavigator's parameters.
Take a look at this documentation

I try to refactor your code.
in component render maybe you can just write :
render() {
const { navigate } = this.props.navigation;
return (
<ScrollView style={{padding: 20}}>
<Button
title="Go to Jane's profile"
onPress={() =>
navigate('Profile', { name: 'AboutDendro' })
}
/>
<Text style={{fontSize: 27}}>{this.state.page}</Text>
<TextInput
placeholder='Email Address'
autoCapitalize='none'
autoCorrect={false}
autoFocus={true}
keyboardType='email-address'
value={this.state.username}
onChangeText={(text) => this.setState({ username: text })} />
<TextInput
placeholder='Password'
autoCapitalize='none'
autoCorrect={false}
secureTextEntry={true}
value={this.state.password}
onChangeText={(text) => this.setState({ password: text })} />
<View style={{margin: 7}}/>
<Button onPress={(e) => this.handleClick(e)} title={this.state.page}/>
<View style={styles.firstView}>
<Text onPress={(e) => this.togglePage(e)} style={styles.buttons}>
{this.alt}
</Text>
</View>
</ScrollView>
);
}
}
And you separate component StackNavigation below component render() like:
const App = StackNavigator({
Home: { screen: Login },
Profile: { screen: AboutDendro },
});
And then import component App in your index.ios.js like:
import './Login';
just that. Maybe my answer can help you.

Related

Converting class based component to function based component fails

I am switching from class-based component to function-based components, but my code works in class-based component and doesn't work in the function-based component.
Here is the code:
import { connect } from "react-redux";
import * as actions from "../redux/actions/authActions";
class Login extends Component {
constructor(props) {
super(props);
this.state = {
email: "",
password: "",
};
}
authenticate() {
this.props.auth(this.state.email, this.state.password).then((response) => {
if (this.props.authenticated) {
alert("User Is Authenticated");
} else {
alert("User Isn't Authenticated");
}
});
}
render() {
return (
<View style={{ flex: 1 }}>
<TextInput
autoCapitalize="none"
keyboardType="email-address"
style={// styles here}
placeholder="Enter email"
value={this.state.email}
onChangeText={(email) => this.setState({ email })}
/>
<TextInput
autoCapitalize="none"
secureTextEntry
style={// styles here}
placeholder="Enter password"
value={this.state.password}
onChangeText={(password) => this.setState({ password })}
/>
<TouchableOpacity onPress={() => this.authenticate()}>
<Text style={{ marginTop: 20, color: "black", textAlign: "center" }}>
Login
</Text>
</TouchableOpacity>
</View>
);
}
}
const mapStateToProps = (state) => ({
isLoggedIn: state.auth.isLoggedIn,
isLoading: state.auth.isLoading,
userData: state.auth.userData,
error: state.auth.error,
authenticated: state.auth.isAuthenticated,
mainState: state,
});
const mapDispatchToProps = (dispatch) => ({
auth: (email, password) => dispatch(actions.loginUser({ email, password })),
});
export default connect(mapStateToProps, mapDispatchToProps)(Login);
Converted code to function based component
import { connect } from "react-redux";
import * as actions from "../redux/actions/authActions";
function Login({ auth, authenticated }) {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const authenticate = () => {
auth(email, password).then((response) => {
if (authenticated) {
alert("User Is Authenticated");
} else {
alert("User Isn't Authenticated");
}
});
};
return (
<View style={{ flex: 1 }}>
<TextInput
autoCapitalize="none"
keyboardType="email-address"
style={ // styles here}
placeholder="Enter email"
value={email}
onChangeText={(text) => setEmail(text)}
/>
<TextInput
autoCapitalize="none"
secureTextEntry
style={ // styles here}
placeholder="Enter password"
value={password}
onChangeText={(text) => setPassword(text)}
/>
<TouchableOpacity onPress={() => authenticate()}>
<Text style={{ marginTop: 20, color: "black", textAlign: "center" }}>
Login
</Text>
</TouchableOpacity>
</View>
);
}
const mapStateToProps = (state) => ({
isLoggedIn: state.auth.isLoggedIn,
isLoading: state.auth.isLoading,
userData: state.auth.userData,
error: state.auth.error,
authenticated: state.auth.isAuthenticated,
mainState: state,
});
const mapDispatchToProps = (dispatch) => ({
auth: (email, password) => dispatch(actions.loginUser({ email, password })),
});
export default connect(mapStateToProps, mapDispatchToProps)(Login);
Here at the Login function. App state isn't updated at the first time, but it gets updated in subsequent attempts.
Thank you for reading and helping.
You've closed over stale state from the render cycle that authenticate was invoked in. React state updates are asynchronous, so if you want to handle state after an update you need to do so in the next render cycle, likely in an useEffect hook (synonymous to the class-based component's componentDidUpdate method). When the authenticated redux state value updates then the component is rerendered.
useEffect(() => {
if (authenticated) {
alert("User Is Authenticated");
} else {
alert("User Isn't Authenticated");
}
}, [authenticated]);
authenticate() {
auth(email, password)
.then((response) => {
console.log(response);
});
}
Update
This useEffect callback will display one alert or the other, each render. You can add state to make it wait until you've submitted an auth request AND have been authenticated.
const [isAuthenticating, setIsAuthenticating] = useState(false);
const [finishedAuth, setFinishedAuth] = useState(false);
useEffect(() => {
if (isAuthenticating && finishedAuth) {
alert(authenticated
? "User Is Authenticated"
: "User Isn't Authenticated"
);
}
}, [isAuthenticating, finishedAuth, authenticated]);
authenticate() {
setIsAuthenticating(true);
auth(email, password)
.then((response) => {
console.log(response);
})
.finally(() => setFinishedAuth(true));
}
These two additional state might be great candidates to instead store in your redux state, BTW.

React Native Expo Infinite Loading State

This is probably a dumb question, but I've been following some react native / expo tutorials on how to make a login screen with Firebase. The tutorial I followed also made a loading screen (using a loading state) that will display while Firebase is connecting. Unfortunately, the loading state never ends for me, and I don't know how to fix it.
Here is my Navigator.js file:
import React, { useReducer } from "react";
import { View, ActivityIndicator } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from "#react-navigation/stack";
import { createDrawerNavigator } from "#react-navigation/drawer";
import { AuthContext } from '../contexts/UserContext';
import { firebase } from "../utils/FirebaseConfig";
import Login from "../screens/Login";
import Signup from "../screens/Signup";
import Home from "../screens/Home";
const Drawer = createDrawerNavigator();
const RootStack = createStackNavigator();
export default AppNavigation = (props) => {
const initialLoginState = {
isLoading: true,
user: null,
};
const loginReducer = (prevState, action) => {
switch (action.type) {
case 'LOGIN':
return {
...prevState,
user: action.user,
isLoading: false,
};
case 'LOGOUT':
return {
...prevState,
user: null,
isLoading: false,
};
case 'REGISTER':
return {
...prevState,
user: action.user,
isLoading: false,
};
}
};
const [loginState, dispatch] = useReducer(loginReducer, initialLoginState);
const authContext = React.useMemo(() => ({
signIn: async (email, password) => {
return firebase
.auth()
.signInWithEmailAndPassword(email, password)
.then(async (userCred) => {
dispatch({ type: 'LOGIN', user: userCred.user });
return true;
}).catch((error) => {
if (error.code === "auth/user-disabled") {
alert("User disabled!");
}
if (error.code === "auth/invalid-email") {
alert("That email address is invalid!");
}
if (error.code === "auth/user-not-found") {
alert("User not found, please sign up!");
}
if (error.code === "auth/wrong-password") {
alert("Wrong password!");
}
return false;
})
},
signOut: async () => {
return firebase.auth().signOut().then(async () => {
dispatch({ type: 'LOGOUT' });
});
},
signUp: (email, password) => {
return firebase.auth().createUserWithEmailAndPassword(email, password).then((userCred) => {
dispatch({ type: 'REGISTER', user: userCred.user });
}).catch((error) => {
if (error.code === "auth/email-already-in-use") {
alert("That email address is already in use!");
}
if (error.code === "auth/invalid-email") {
alert("That email address is invalid!");
}
if (error.code === "auth/operation-not-allowed") {
alert("Operation is not allowed!");
}
if (error.code === "auth/weak-password") {
alert("The password is too weak!");
}
return false;
})
}
}), []);
if (loginState.isLoading) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<ActivityIndicator size="large" color="grey" />
</View>
);
}
return (
<AuthContext.Provider value={authContext}>
<NavigationContainer>
{loginState.user !== null ? (
<Drawer.Navigator >
<Drawer.Screen name="Home" user={loginState.user} component={Home} />
</Drawer.Navigator>
) :
(
<RootStack.Navigator headerMode='none'>
<RootStack.Screen name="Login" component={Login} />
<RootStack.Screen name="Signup" component={Signup} />
</RootStack.Navigator>
)
}
</NavigationContainer>
</AuthContext.Provider>
)
}
Here is my Home.js File:
import React from 'react';
import { useContext } from 'react';
import { Text, TouchableOpacity, View } from 'react-native';
import { AuthContext } from "../contexts/UserContext";
function Home(props) {
const { signOut } = useContext(AuthContext);
return (
<View style={{ flex: 1 }}>
<Text>Welcome</Text>
<Text>Email: {props.user?.email}</Text>
<Text>uid: {props.user?.uid}</Text>
<Text>displayName: {props.user?.displayName}</Text>
<Text>photo: {props.user?.photoURL}</Text>
<TouchableOpacity onPress={() => signOut()} style={{ flexDirection: "row", alignItems: "center", justifyContent: "center", width: "100%" }} >
<Text style={{ fontWeight: "bold", fontSize: 18 }}>Logout</Text>
</TouchableOpacity>
</View>
);
}
export default Home;
Here is the Login.js file:
import React, { useContext, useState } from 'react';
import { KeyboardAvoidingView, View, Text, TextInput } from 'react-native';
import { AuthContext } from "../contexts/UserContext";
function Login(props) {
const [data, setData] = useState({
email: "",
password: ""
})
const { signIn } = useContext(AuthContext);
const emailInputChange = (val) => {
setData({
...data,
email: val
})
}
const passwordChange = (val) => {
setData({
...data,
password: val
});
}
const LoginHandle = () => {
signIn(data.email, data.password)
}
return (
<KeyboardAvoidingView>
<View style={{ flex: 1 }}>
<Text>Email: </Text>
<View >
<TextInput
placeholder="Email"
autoCapitalize="none"
onChangeText={(val) => emailInputChange(val)}
/>
</View>
<Text>Password: </Text>
<View>
<TextInput
placeholder="Password"
autoCapitalize="none"
secureTextEntry={true}
onChangeText={(val) => passwordChange(val)}
/>
</View>
<TouchableOpacity onPress={() => LoginHandle()} style={{ width: "100%", height: 50, justifyContent: "center", alignItems: "center", borderRadius: 10 }}>
<Text style={{ color: "#FFF", fontSize: 18, fontWeight: "bold" }}>Login</Text>
</TouchableOpacity>
</View>
</KeyboardAvoidingView>
);
}
export default Login;
And finally, the Signup.js file:
import React, { useContext, useState } from 'react';
import { KeyboardAvoidingView, View, Text, TextInput } from 'react-native';
import { AuthContext } from "../contexts/UserContext";
function Signup(props) {
const [data, setData] = useState({
email: "",
password: ""
})
const { signUp } = useContext(AuthContext);
const emailInputChange = (val) => {
setData({
...data,
email: val
})
}
const passwordChange = (val) => {
setData({
...data,
password: val
});
}
const SignupHandle = () => {
signUp(data.email, data.password)
}
return (
<KeyboardAvoidingView>
<View style={{ flex: 1 }}>
<Text>Email: </Text>
<View >
<TextInput
placeholder="Email"
autoCapitalize="none"
onChangeText={(val) => emailInputChange(val)}
/>
</View>
<Text>Password: </Text>
<View>
<TextInput
placeholder="Password"
autoCapitalize="none"
secureTextEntry={true}
onChangeText={(val) => passwordChange(val)}
/>
</View>
<TouchableOpacity onPress={() => SignupHandle()} style={{ width: "100%", height: 50, justifyContent: "center", alignItems: "center", borderRadius: 10 }}>
<Text style={{ color: "#FFF", fontSize: 18, fontWeight: "bold" }}>Signup</Text>
</TouchableOpacity>
</View>
</KeyboardAvoidingView>
);
}
export default Signup;

undefined is not an object (evaluating '_ref.navigation') React-native navigation error

How to solve this error in react navigation
I am can't able to navigate another screen from passReg() function,
check bellow my full code on my answer
This is my error
THIS IS MY CODE PLZ SOLVE THIS ERROR
import 'react-native-gesture-handler';
import React,{ useState } from 'react';
import { StyleSheet, Text, SafeAreaView, ScrollView , View,Image,FlatList,RefreshControl,AsyncStorage,TextInput} from 'react-native';
import { TouchableRipple,Button} from 'react-native-paper';
import { useNavigation,NavigationContainer} from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import firebase from 'firebase';
import auth from '#react-native-firebase/auth';
import Reg from './Reg';
const Stack = createStackNavigator();
function passReg({ navigation })
{
navigation.navigate('reg');
}
const PhoneSignIn=()=> {
// If null, no SMS has been sent
const [number, setNumber] = useState(null);
const [confirm, setConfirm] = useState(null);
const [code, setCode] = useState('');
const [flag, setFlag] = useState();
// Handle the button press
async function signInWithPhoneNumber(phoneNumber) {
const addNum = '+91'+phoneNumber;
try{
const confirmation = await auth().signInWithPhoneNumber(addNum);
setConfirm(confirmation);
} catch (error) {
alert(error);
}
}
async function confirmCode() {
try {
await confirm.confirm(code);
if (confirm.confirm(code)) {
AsyncStorage.setItem('mo_num',number);
alert("Congraulation....")
datasend();
}
} catch (error) {
alert(error);
}
}
async function datasend()
{
fetch('https://punjabfoodhub.in/app/reg.php', {
method: 'POST',
mode: 'no-cors',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
'phone_num': number,
})
}).then((response) => response.json())
.then((json) => {
setFlag(json.flag);
if (flag == 'reg') { passReg()}
}).catch((err) => { console.log(err); });
}
if (!confirm) {
return (
<>
<Image
source={require('../assets/cover.png')}
style={styles.image}
/>
<View style={{padding:18}}>
<TextInput
style={styles.input}
placeholder="+91 **********"
onChangeText={num => setNumber(num)}
keyboardType="numeric"
autoCompleteType="tel"
dataDetectorTypes="phoneNumber"
/>
<Button icon="phone" mode="contained" style={styles.btn} onPress={() => passReg()}>
SEND OTP
</Button>
</View>
</>
);
}
return (
<>
<Image
source={require('../assets/cover.png')}
style={styles.image}
/>
<View style={{padding:18}}>
<TextInput
style={styles.input}
maxLength = {6}
onChangeText={text => setCode(text)}
keyboardType="numeric"
placeholder="OTP"
/>
<Button icon="camera" mode="contained" style={styles.btn} onPress={()=> confirmCode()}>
Next
</Button>
<Button mode="text" color="gold" onPress={() => console.log('Pressed')}>
Resend OTP ?
</Button>
</View>
</>
);
}
export default class Login extends React.Component{
constructor(props) {
super(props);
this.state = {
number:null,
otpsend:false,
confirm:null,
otp:null,
};
}
render(){
return(
<ScrollView style={{backgroundColor:'#fff'}}>
<PhoneSignIn/>
<Stack.Navigator headerMode="none">
<Stack.Screen name="main" component={PhoneSignIn} />
<Stack.Screen name="reg" component={Reg} />
</Stack.Navigator>
</ScrollView>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#FBFCFC', //#FFFAFA
paddingHorizontal:12,
//marginTop: Constants.statusBarHeight,
},
image:{
width:'100%',
height:250
},
input:{
borderRadius:20,
borderWidth: 2,
borderColor:'gold',
paddingHorizontal:20,
fontSize:18
, },
btn:{
borderRadius:20,
backgroundColor:'gold',
paddingVertical:5,
marginTop:8
}
});
I believe this has to do with the deconstruction of the navigation prop.
In the line function passReg({ navigation }), there is probably data that's supposed to be there but is not coming through. I'll check back in when I'm able to find the solution for my exact same problem....

Message not showing up in my react native chat bot

I'm making a chat bot app in react native and I am facing some difficulty in showing the messages that are saved in my firebase. The message box shows up empty. Moreover, three messages show up whereas there is only one message in my firebase. I am using React-Redux for state management and react-native-router-flux for navigation
Here is the code of my Login.js:
import React, {Component} from 'react'
import {View, Text, TouchableOpacity, StatusBar, ImageBackground} from 'react-native'
import {connect} from 'react-redux'
import {login, loginUser} from '../actions'
import {Input, Card, Button, Spinner} from './common'
class Login extends Component {
loginUser() {
const {email, password} = this.props
this.props.loginUser({email, password})
}
renderButton() {
if(this.props.loading) {
return <Spinner size='large' />
}
return (
<Button style={{backgroundColor: '#2D99FC', color: 'white'}}
text='Sign in'
onPress={this.loginUser.bind(this)}
/>
)
}
render() {
return(
<ImageBackground
style={{width: '100%', height: '100%'}}
source={require('../assets/images/bg.jpg')}
>
<StatusBar hidden />
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<Text style={{fontSize: 25, fontWeight: 'bold', margin: 10}}>Login</Text>
<Text style={{color: 'grey', margin: 10}}>Stay Connected</Text>
<Card>
<Input
placeholder='name#example.com'
iconName='user'
value={this.props.email}
onChangeText={value => this.props.login({prop: 'email', value})}
/>
<Input
placeholder="******"
iconName='lock'
secureTextEntry
value={this.props.password}
onChangeText={value => this.props.login({prop: 'password', value})}
/>
<Text style={{fontSize: 20, color: 'red'}}>
{this.props.error}
</Text>
{this.renderButton()}
<TouchableOpacity>
<Text style={{color:'#2D99FC', fontWeight: 'bold', margin: 10, marginBottom: 30}}>Forgot Password?</Text>
</TouchableOpacity>
<View style={{flexDirection: 'row', margin: 10}}>
<Text>Don't have an account? </Text>
<TouchableOpacity>
<Text style={{color:'#2D99FC', fontWeight: 'bold'}}>Sign Up</Text>
</TouchableOpacity>
</View>
</Card>
</View>
</ImageBackground>
);
}
}
const mapStateToProps = state => {
const {email, password, loading, error} = state.auth
return {email, password, loading, error}
}
export default connect(mapStateToProps, {login, loginUser})(Login)
Here is my code of AuthAction.js:
import {AsyncStorage} from 'react-native'
import firebase from 'firebase'
import {Actions} from 'react-native-router-flux'
import User from '../User'
import {REGISTER, SIGN_UP_USER, SIGN_UP_USER_SUCCESS, SIGN_UP_USER_FAIL, LOGIN, LOGIN_USER, LOGIN_USER_SUCCESS, LOGIN_USER_FAIL, UPDATE_USERS} from './types'
export const register = ({prop, value}) => {
return {
type: REGISTER,
payload: {prop, value}
}
}
export const createUser = ({email, password, conPass, name}) => {
return(dispatch) => {
dispatch({type: SIGN_UP_USER})
if(password !== conPass) {
signupUserFail(dispatch, 'Passwords do not match')
}
else {
firebase.auth().createUserWithEmailAndPassword(email, password)
.then(user => {
signupUserSuccess(dispatch, user)
addData(name, email)
})
.catch(() => signupUserFail(dispatch, 'Authentication Failed'))
}
}
}
const addData = async (name, email) => {
await AsyncStorage.setItem('userName', name)
await AsyncStorage.setItem('userEmail', email)
User.name = name
User.email = email
firebase.database().ref('users/' + User.name).set({name, email})
}
const signupUserSuccess = (dispatch, user) => {
dispatch({
type: SIGN_UP_USER_SUCCESS,
payload: user
})
}
const signupUserFail = (dispatch, error) => {
dispatch({
type: SIGN_UP_USER_FAIL,
payload: error
})
}
export const login = ({prop, value}) => {
return {
type: LOGIN,
payload: {prop, value}
}
}
export const loginUser = ({email, password}) => {
return(dispatch) => {
dispatch({type: LOGIN_USER})
firebase.auth().signInWithEmailAndPassword(email, password)
.then(user => loginUserSuccess(dispatch, user))
.catch(() => loginUserFail(dispatch, 'Authentication Failed'))
}
}
const loginUserSuccess = (dispatch, user) => {
dispatch({
type: LOGIN_USER_SUCCESS,
payload: user
})
firebase.database().ref('users')
.on('child_added', (val) => {
let person = val.val()
person.name = val.key
dispatch({type: UPDATE_USERS, payload: person})
})
Actions.chat()
}
const loginUserFail = (dispatch, error) => {
dispatch({
type: LOGIN_USER_FAIL,
payload: error
})
}
Here is my code to AuthReducer.js:
import {REGISTER, SIGN_UP_USER, SIGN_UP_USER_SUCCESS, SIGN_UP_USER_FAIL, LOGIN, LOGIN_USER, LOGIN_USER_SUCCESS, LOGIN_USER_FAIL, UPDATE_USERS} from '../actions/types'
import User from '../User'
const INITIAL_STATE = {email: '', password: '', conPass: '', loading: false, error: '', user: null, name: '', user: []}
export default (state = INITIAL_STATE, action) => {
console.log(action)
switch(action.type) {
//Registration
case REGISTER:
return {...state, [action.payload.prop]: action.payload.value}
case SIGN_UP_USER:
return {...state, loading: true, error: ''}
case SIGN_UP_USER_SUCCESS:
return {...state, ...INITIAL_STATE, user: action.payload}
case SIGN_UP_USER_FAIL:
return {...state, error: action.payload, password: '', conPass: '', loading: false}
//Login
case LOGIN:
return {...state, [action.payload.prop]: action.payload.value}
case LOGIN_USER:
return {...state, loading: true, error: ''}
case LOGIN_USER_SUCCESS:
return {...state, ...INITIAL_STATE, user: action.payload}
case LOGIN_USER_FAIL:
return {...state, error: action.payload, password: '', loading: false}
case UPDATE_USERS:
User.name = action.payload.name
User.email = action.payload.email
//default
default:
return state
}
}
Here is my code to Chat.js:
import React, {Component} from 'react'
import {View, SafeAreaView, Text, TextInput, TouchableOpacity, StatusBar, Dimensions, FlatList} from 'react-native'
import {connect} from 'react-redux'
import {messageChanged, sendMessage, messagesListFetch} from '../actions'
import { Header } from './common';
import User from '../User';
class Chat extends Component {
onMessageChange(text) {
this.props.messageChanged(text)
}
sendMessage() {
const {message} = this.props
this.props.sendMessage(message)
}
componentDidMount() {
this.props.messagesListFetch()
}
render() {
return(
<View>
<View>
<StatusBar hidden />
<Header text='Chat with Me' />
</View>
<SafeAreaView>
<FlatList
scrollEnabled
style={{padding: 10, height: Dimensions.get('window').height * 0.8}}
data={this.props.messageList}
renderItem={(item) => {
return(
<View style={{
flexDirection: 'row',
width: '60%',
alignSelf: item[0] === User.name ? 'flex-end' : 'flex-start',
backgroundColor: item[0] === User.name ? '#00897B' : '#7CB342',
borderRadius: 5,
marginBottom: 10
}}>
<Text style={{color: '#FFF', padding: 7, fontSize: 16}}>{item[1]}</Text>
<Text style={{color: '#EEE', padding: 3, fontSize: 12}}>{item[2]}</Text>
</View>
)
}}
keyExtractor={(item, index) => item[0]}
/>
<View style={{flexDirection: 'row', alignItems: 'center', marginHorizontal: 5}}>
<TextInput
style={styles.input}
placeholder='Type a message...'
value={this.props.message}
onChangeText={this.onMessageChange.bind(this)}
/>
<TouchableOpacity onPress={this.sendMessage.bind(this)} style={{paddingBottom: 10, marginLeft: 5}}>
<Text>Send</Text>
</TouchableOpacity>
</View>
</SafeAreaView>
</View>
);
}
}
const styles = {
input: {
padding: 10,
borderWidth: 1,
borderColor: '#CCC',
width: '80%',
marginBottom: 10,
borderRadius: 5,
},
}
const mapStateToProps = state => {
let messages = state.chat.messageList
let messageList = []
Object.keys(messages).map((key, index) => {
messageList.push(messages[key])
})
let message = state.chat.message
return {message, messageList}
}
export default connect(mapStateToProps, {messageChanged, sendMessage, messagesListFetch})(Chat)
Here is my code to ChatActions.js:
import firebase from 'firebase'
import {MESSAGE_CHANGED, MESSAGE_SENT, GET_MESSAGE_LIST} from './types'
import User from '../User'
export const messageChanged = (text) => {
return {
type: MESSAGE_CHANGED,
payload: text
}
}
export const sendMessage = (textMessage) => {
return(dispatch) => {
if(textMessage.length > 0) {
console.log(User.name)
let msgId = firebase.database().ref('messages').child(User.name).child('Bot').push().key
let updates = {}
let message = {
message: textMessage,
time: firebase.database.ServerValue.TIMESTAMP,
from: User.name
}
updates['messages/' + User.name + '/' + 'Bot' + '/' + msgId] = message
updates['messages/' + 'Bot' + '/' + User.name + '/' + msgId] = message
firebase.database().ref().update(updates)
dispatch({type: MESSAGE_SENT})
}
}
}
export const messagesListFetch = () => {
return(dispatch) => {
setTimeout(() => {
firebase.database().ref('messages').child(User.name).child('Bot')
.on('child_added', (value) => {
dispatch({type: GET_MESSAGE_LIST, payload: value.val()})
// console.log(value.val())
})
}, 1000)
}
}
Here is my code to ChatReducer.js:
import {MESSAGE_CHANGED, MESSAGE_SENT, GET_MESSAGE_LIST} from '../actions/types'
const INITIAl_STATE = {message: '', messageList: []}
export default (state = INITIAl_STATE, action) => {
switch(action.type) {
case MESSAGE_CHANGED:
return {...state, message: action.payload}
case MESSAGE_SENT:
return {...state, message: ''}
case GET_MESSAGE_LIST:
return {...state, messageList: action.payload}
default:
return state
}
}
Here is my User.js:
User = {
name: '',
email: ''
}
export default User
I want the message to show, and to show only once, not thrice. How can I do that? Can anyone help me here?

OneSignal not working after update React Native Android

I have followed the guidelines of version 3.2.12,
and followed the instruction in the official document, but player id is not getting generated please help.
Initialization stopped after upgradation to 3.2.12, now they are not supporting initialization on componentWillMount()
import React, { Component } from "react";
import {
Text,
View,
Image,
TouchableOpacity,
I18nManager,
AsyncStorage,
Platform
} from "react-native";
import {
Container,
Right,
Item,
Input,
Header,
Left,
Body,
Title,
Form
} from "native-base";
import FontAwesome from "react-native-vector-icons/FontAwesome";
import Ionicons from 'react-native-vector-icons/Ionicons';
// Screen Styles
import styles from "../Theme/Styles/Signin";
import Logo from "../image/qualpros.png";
import axios from 'axios';
import AwesomeAlert from 'react-native-awesome-alerts';
import OneSignal from 'react-native-onesignal';
class TutorSignInScreen extends Component {
static navigationOptions = {
header: null,
showAlert: false,
message: '',
}
state = {
data: [],
email: null,
password: null,
device_id: null,
showAlert : false
}
constructor(properties) {
super(properties);
OneSignal.init("my-onesignal-id");
OneSignal.addEventListener('received', this.onReceived);
OneSignal.addEventListener('opened', this.onOpened);
OneSignal.addEventListener('ids', this.onIds);
}
componentWillUnmount() {
OneSignal.removeEventListener("received", this.onReceived);
OneSignal.removeEventListener("opened", this.onOpened);
OneSignal.removeEventListener("ids", this.onIds);
}
onReceived(notification) {
console.log("Notification received: ", notification);
}
onOpened(openResult) {
console.log("Message: ", openResult.notification.payload.body);
console.log("Data: ", openResult.notification.payload.additionalData);
console.log("isActive: ", openResult.notification.isAppInFocus);
console.log("openResult: ", openResult);
}
onIds(device) {
let playerid = device.userId;
//console.log("Device info: ", playerid);
AsyncStorage.setItem('playerid', playerid);
this.setState ({
device_id: playerid
})
}
showAlert = () => {
this.setState({
showAlert: true
});
};
hideAlert = () => {
this.setState({
showAlert: false
});
};
signIn = async () => {
let device_type = (Platform.OS === 'ios') ? 'ios' : 'android'
try {
let { data } = await axios.post('url', {
email: this.state.email,
password: this.state.password,
//device_id: this.state.device_id,
device_id: '123test',
device_type: device_type
})
.then((response) => {
if (response.data.data.status === 'success') {
this.setState({ data: response.data.data })
console.log(response.data.data)
AsyncStorage.setItem('username', response.data.data.user_info.username);
AsyncStorage.setItem('userType', response.data.data.user_info.user_role_name);
AsyncStorage.setItem('latitude', response.data.data.user_info.latitude);
AsyncStorage.setItem('longitude', response.data.data.user_info.longitude);
AsyncStorage.setItem('user_id', response.data.data.user_info.user_id.toString());
AsyncStorage.setItem('user_role_id', response.data.data.user_info.user_role_id.toString());
this.props.navigation.navigate(response.data.data.user_info.user_role_name === 'Student' ? 'App' : 'Tutor')
} else {
this.setState({
message: response.data.data.message,
showAlert: true,
})
}
})
} catch (err) {
console.log(err);
}
}
showAlert = () => {
this.setState({
showAlert: true
});
};
hideAlert = () => {
this.setState({
showAlert: false
});
};
render() {
return (
<Container>
<Header style={styles.header}>
<Left style={styles.left}>
<TouchableOpacity
style={styles.backArrow}
onPress={() => this.props.navigation.navigate("Welcome")}
>
<View style={{ flexDirection: "row" }}>
<FontAwesome name="angle-left" size={30} color="black" />
<Text style={{ margin: 5, marginTop: 6, color: "black", fontSize: 12}}>Back</Text>
</View>
</TouchableOpacity>
</Left>
<Body style={styles.body} />
<Right style={styles.right} />
</Header>
<View style={styles.logosec}>
<Image source={Logo} style={styles.logostyle} />
</View>
<Form style={styles.form}>
<Item rounded style={styles.inputStyle}>
<Input
textAlign={I18nManager.isRTL ? "right" : "left"}
placeholder="Email"
style={styles.inputmain}
onChangeText={(email) => { this.setState({ email }) }}
autoCapitalize='none'
/>
</Item>
<Item rounded style={[styles.inputStyle, { marginTop: 10 }]}>
<Input
placeholder="Password"
secureTextEntry={true}
textAlign={I18nManager.isRTL ? "right" : "left"}
style={styles.inputmain}
onChangeText={(password) => { this.setState({ password }) }}
autoCapitalize='none'
/>
</Item>
<TouchableOpacity
info
style={styles.signInbtn}
onPress={this.signIn}
>
<Text autoCapitalize="words" style={styles.buttongetstarted}>
Sign In
</Text>
</TouchableOpacity>
<TouchableOpacity onPress={() => this.props.navigation.navigate('ForgetPassword')}>
<Text autoCapitalize="words" style={styles.buttongettext}>
Forgot your password?
</Text>
</TouchableOpacity>
</Form>
<View style={styles.bottomView}>
{/* <TouchableOpacity
style={styles.fbButton}
onPress={() => alert("Facebook button Clicked")}
>
<View iconRight style={styles.fbview}>
<Ionicons name="logo-linkedin" size={30} color="white" />
<Text autoCapitalize="words" style={styles.fbButtonText}>
Sign in with LinkedIn
</Text>
</View>
</TouchableOpacity> */}
<TouchableOpacity
style={styles.bottomText}
onPress={() => { this.props.navigation.navigate('TutorSignUpScreen') }}>
<Text style={styles.bottomText01}>
Don&apos;t have an account?{" "}
<Text style={styles.bottomText02}>Sign up</Text>
</Text>
</TouchableOpacity>
</View>
<AwesomeAlert
show={this.state.showAlert}
showProgress={false}
//title="QualPros!"
message={this.state.message}
closeOnTouchOutside={true}
closeOnHardwareBackPress={false}
showConfirmButton={true}
confirmText="Ok"
confirmButtonColor="#d91009"
onConfirmPressed={() => {
this.hideAlert();
}}
/>
</Container>
);
}
}
export default TutorSignInScreen;
environment:
"react-native-onesignal": "^3.2.12",
"react": "16.6.1",
"react-native": "0.57.7"

Categories