In my react native mobile app I have a login functionality and register functionality. User is logged in using email and password using firebase authentication. After logged in I need to be able to show user's name in the header component. But in my app I am using stack navigator, drawer navigator and bottom tab navigator. So, for navigation I have created separate js file called Router.
const ThirdNavigator = createBottomTabNavigator({
LoginForm,
RegisterForm
});
const SecondNavigator = createDrawerNavigator({
Profile: {
screen: TaskList,
navigationOptions: ({ navigation }) => ({
title: 'Your Schedule'
})
}
}, {
// drawerType: 'slide',
});
const MainNavigator = createStackNavigator({
Open: { screen: OpenWindow },
Home: {
screen: ThirdNavigator,
navigationOptions: ({ navigation }) => ({
title: 'Sign In',
headerStyle: { backgroundColor: '#0680EC', height: 45 },
headerLeft: null,
headerRight: null
})
},
Profile: {
screen: SecondNavigator,
navigationOptions: ({ navigation }) => ({
title: 'Your Schedule',
headerStyle: { backgroundColor: '#0680EC', height: 45 },
headerLeft: <Toggle navigation={navigation} />,
headerRight: <Notification logOutUser={logOutUser()} />
})
}
});
const Router = createAppContainer(MainNavigator);
export default connect(null, { emailChanged, passwordChanged, loginUser, logOutUser })(Router);
As I got to know, when I am using react-redux connect function, I can't use navigation options in main UI component. So, I had to use navigation options in Router. My header is a separate component called Notification.js.
class Notification extends Component {
state = {
user_name: 'label',
loading: true,
level: ''
};
onSelectOpt(idx, value) {
this.setState({ level: value });
if (value === "Logout") {
firebase.auth().signOut();
}
}
showLogout() {
return (
<ModalDropdown options={[this.state.user_name, 'Logout']} onSelect={(idx, value) => this.onSelectOpt(idx, value)} style={{ width: '100%', height: 30, justifyContent: 'center', paddingLeft: 20 }} dropdownStyle={{ width: 100, height: 82, paddingBottom: 0 }} dropdownTextStyle={{ color: '#000', fontSize: 15 }} dropdownTextHighlightStyle={{ fontWeight: 'bold' }} >
<View style={{ height: 30, width: 60, alignItems: 'center', paddingRight: 20 }}>
<Image
source={require('../pics/logout.png')}
style={styles.downStyle}
/>
</View>
</ModalDropdown>
);
}
render() {
return (
<View style={{ flexDirection: 'row', paddingRight: 10 }}>
<View style={{ height: 30, width: 60, backgroundColor: 'transparent' }}>
{this.showLogout()}
</View>
</View>
)
}
}
const styles = {
imageStyle: {
width: 25,
height: 25
},
buttonStyle: {
marginLeft: 5,
marginRight: 7
},
spinnerStyle: {
alignSelf: 'stretch',
borderRadius: 5,
marginLeft: 20,
marginRight: 20,
borderRadius: 60,
paddingTop: 10,
paddingBottom: 10,
height: 100
},
downStyle: {
width: 25,
height: 25
}
}
export { Notification };
My problem is, after I fetched user's name from firebase database, how can I pass it as a prop to my header. I call my action creator in main UI component after logged in. But navigation options are in Router. So, I'm looking for a way to pass fetched data as a prop to Header(Notification.js).
class TaskList extends Component {
handleBackButtonClick() {
BackHandler.exitApp();
return true;
}
UNSAFE_componentWillMount() {
this.props.userFetch();
// console.log(this.props.username.name);
BackHandler.addEventListener('hardwareBackPress', this.handleBackButtonClick.bind(this));
}
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress', this.handleBackButtonClick.bind(this));
}
UNSAFE_componentWillReceiveProps(nextProps) {
// console.log(nextProps.username);
if (firebase.auth().currentUser == null) {
this.props.navigation.navigate('Home');
}
}
render() {
console.log(this.props);
return (
<View>
<Text>Employee</Text>
<Text>Employee</Text>
<Text>Employee</Text>
<Text>Employee</Text>
<Text>Employee</Text>
<Text>Employee</Text>
</View>
);
}
}
const mapStateToProps = state => {
const username = _.map(state.username, (val, uid) => {
return { ...val, uid };
});
return { username };
}
export default connect(mapStateToProps, { userFetch })(TaskList);
I have successfully fetched data from firebase and converted it into a array in main UI. Now I want a way to pass that data to the header Notification.js component. Please help me to figure out a way to do this.
Related
How to create a slide down and up notification indicator in react native see below for and example
I would like the notification to slide down for about 3 seconds at the top of the screen and slide up back off the screen after 3 seconds
I tried this below but it is not working
const [stateAnimate, setAnimate] = useState(new Animated.Value(300));
const slideDown = () => {
Animated.spring(stateAnimate, {
toValue: 0,
}).start();
slideUp();
};
const slideUp = setTimeout(() => {
Animated.spring(stateAnimate, {
toValue: 0,
}).start();
clearTimeout(slideUp);
}, 3000);
<View>
<Animated.View style={[{ position: 'absolute', right: 0,left:0,backgroundColor: '#0400ff', height: '20%', width: '100%', }, { transform: [{ translateX: stateAnimate }] }]}>
<Text style={{ fontSize: 16, color: '#fff', alignSelf: 'center',marginTop:10 }}>loading please wait...</Text>
</Animated.View>
<View style={{ marginTop: 200 }}>
<Button
title="Slide"
onPress={() => {
slideDown();
}}
/>
</View>
</View>
I made a Toast like this in my app.
Toast.js:
import React from 'react';
import {Image, SafeAreaView, FlatList, TextInput, ScrollView, View, TouchableOpacity, Text} from 'react-native';
import * as Animatable from 'react-native-animatable';
import SafeArea, { type SafeAreaInsets } from 'react-native-safe-area'
export default class Toast extends React.Component {
singletonInstance = null;
state = {
visible: false,
title: "",
description: "",
backgroundColor: "",
textColor: ""
}
componentDidMount() {
Toast.singletonInstance = this;
this._isMounted = true;
SafeArea.getSafeAreaInsetsForRootView().then((result) => {
this.setState({safeInsetTop: result.safeAreaInsets.top});
});
}
componentWillUnmount() {
this._isMounted = false;
this.setState = (state,callback)=>{
return;
};
}
static show(title, description, backgroundColor, textColor) {
Toast.singletonInstance._openPanel(title, description, backgroundColor, textColor);
}
_openPanel(title, description, backgroundColor, textColor) {
if (this._isMounted) {
this.setState({
visible: true,
title: title,
description: description,
backgroundColor: backgroundColor,
textColor: textColor
});
this.setCloseTimer()
} else {
this._isMounted = true;
}
};
close = () => {
if (this._isMounted) {
if (this.view != null) {
this.view.fadeOutUp().then(endState =>
this.setState({visible: false})
);
} else {
this.setState({visible: false})
}
}
};
setCloseTimer() {
this.closeTimer = setTimeout(() => {
this.close()
}, 4000);
}
handleViewRef = ref => this.view = ref;
render() {
if (this.state.visible) {
return (
<View style={{width: '100%', position: 'absolute', top: 0, left: 0, right: 0}}>
<Animatable.View ref={this.handleViewRef} animation="slideInDown" style={{flex: 1, paddingTop: this.state.safeInsetTop, paddingHorizontal: 20, paddingBottom: 20, backgroundColor: this.state.backgroundColor}} >
<Text ellipsizeMode='tail' numberOfLines={1} style={{fontFamily: "Nunito-ExtraBold", fontSize: 12, width: '100%', marginLeft: 6, marginTop: 4, color: this.state.textColor}}>{this.state.title}</Text>
<Text ellipsizeMode='tail' style={{fontFamily: "Nunito-Bold", fontSize: 18, width: '100%', marginLeft: 6, marginTop: 4, color: this.state.textColor}}>{this.state.description}</Text>
</Animatable.View>
</View>
)
} else {
return null;
}
}
}
And then I use it in my other files like this:
...
import Toast from '../components/Toast.js'
...
...
Toast.show("Warning!", "You are about to delete everything", "white", "red");
...
I'm sure there is a prettier solution or a module somewhere, but it works for me :-)
You can use react-native-paper
Banner- React Native Paper
import React from 'react';
import { Banner } from 'react-native-paper';
const MyComponent = () => {
const [visible, setVisible] = React.useState(true);
return <Banner
visible={visible}
actions={[
{
label: 'Fix it',
onPress: () => setVisible(false),
},
{
label: 'Learn more',
onPress: () => setVisible(false),
},
]}
icon={({size}) => (
<Image
source={{
uri: 'https://avatars3.githubusercontent.com/u/17571969?s=400&v=4',
}}
style={{
width: size,
height: size,
}}
/>
)}>
There was a problem processing a transaction on your credit card.
</Banner>
}
I am having 2 problems using React Native and Firebase Real Time Database.
When I add something to the list with the text input, all the list itens are duplicated except the item that I just added, this problem is only solved when I refresh the app screen.
When I remove something from firebase dashboard or other client, the list is not updated real time.
import React, {useState, Component} from 'react';
import {
Text,
View,
Switch,
StyleSheet,
FlatList,
TextInput,
Button,
TouchableOpacity,
SafeAreaView,
VirtualizedList,
} from 'react-native';
import database from '#react-native-firebase/database';
class MenuBreakFastScreen extends React.Component {
state = {newItem: ''};
state = {itens: []};
componentDidMount() {
let dbRef = database().ref('/cafe/itens/');
this.listenerFirebase(dbRef);
}
listenerFirebase(dbRef) {
dbRef.on('value', dataSnapshot => {
const newItens = JSON.parse(JSON.stringify(this.state.itens));
dataSnapshot.forEach(child => {
newItens.push({
name: child.val().name,
key: child.key,
});
this.setState({itens:newItens});
});
});
}
addItem() {
if (this.state.newItem === '') {
return;
}
database().ref('/cafe/itens/').push({
name: this.state.newItem,
});
this.setState({
newItem: '',
});
}
render() {
const {itens} = this.state;
const {newItem} = this.state;
const renderItem = ( {item}) => {
return(
<ItemAsset title={item.name}/>
);
}
return (
<SafeAreaView
style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<FlatList
data={itens}
renderItem={renderItem}
keyExtractor={item => item.key}
/>
<SafeAreaView style={{flexDirection: 'row'}}>
<TextInput
style={styles.input}
onChangeText={text =>
this.setState({
newItem: text,
})
}
value={newItem}
/>
<TouchableOpacity style={styles.Botao} onPress={() => this.addItem()}>
<Text style={styles.BotaoTexto}>+</Text>
</TouchableOpacity>
</SafeAreaView>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
texto: {
fontSize: 35,
},
input: {
color: '#000',
fontSize: 22,
borderWidth: 1,
flex: 8,
margin: 10,
},
BotaoTexto: {
color: '#fff',
fontSize: 22,
},
Botao: {
backgroundColor: '#000',
marginTop: 10,
padding: 10,
flex: 1,
alignItems: 'center',
margin: 10,
},
ListaContainer: {
flexDirection: 'row',
backgroundColor: '#000',
flex: 1,
},
item: {
backgroundColor: '#000',
padding: 20,
marginVertical: 8,
marginHorizontal: 16,
flexDirection: 'row',
},
title: {
color: '#ffff',
fontSize: 32,
},
});
const ItemAsset = ( {title} ) => {
return(
<View style={styles.item}>
<Text style={styles.title}>{title}</Text>
</View>
);
}
export default MenuBreakFastScreen;
When you are listen for real time changes on real-time database it will send all the items with snapshot when any data is changed. That happens because you are listen for whole list, not only for a single item. Therefore you do not need to get the current list from state. You just have to set the state with retrieved data.
listenerFirebase(dbRef) {
dbRef.on('value', dataSnapshot => {
const newItens = []; // This should be initially empty array. That's all.
dataSnapshot.forEach(child => {
newItens.push({
name: child.val().name,
key: child.key,
});
});
this.setState({itens:newItens});
});
}
After correcting this part the error you got when removing data will be also resolved.
I know there have been similar questions, but I tried anyway and still can't find the solution.
I have a login screen, registration, chat and a test screen (where I use just to try to fix this error) I want to pass the name, email and avatar data that I get there from Login / Register, but it is returned to me that the object is undefined. I only corrected the error if I put the navigation as follows: Login or Register> Chat. However, I do not want to do so, I need to click on an image and direct to this chat. Apparently it's a common mistake, but I'm frustrated with trying to fix it (I'm new to React-Native)
Chat.js
import { GiftedChat } from "react-native-gifted-chat"; // 0.3.0
import firebaseSvc from "../FirebaseSvc";
type Props = {
name?: string,
email?: string,
avatar?: string
};
class Chat extends React.Component<Props> {
constructor(props) {
super(props);
}
static navigationOptions = ({ navigation }) => ({
title: (navigation.state.params || {}).name || "Chat!"
});
state = {
messages: []
};
get user() {
return {
name: this.props.navigation.state.params.name,
email: this.props.navigation.state.params.email,
avatar: this.props.navigation.state.params.avatar,
id: firebaseSvc.uid,
_id: firebaseSvc.uid // need for gifted-chat
};
}
render() {
return (
<GiftedChat
messages={this.state.messages}
onSend={firebaseSvc.send}
user={this.user}
/>
);
}
componentDidMount() {
firebaseSvc.refOn(message =>
this.setState(previousState => ({
messages: GiftedChat.append(previousState.messages, message)
}))
);
}
componentWillUnmount() {
firebaseSvc.refOff();
}
}
export default Chat;
Login.js
import { Constants, ImagePicker, Permissions } from "expo";
import {
StyleSheet,
Text,
TextInput,
TouchableOpacity,
KeyboardAvoidingView,
View,
Button,
ImageEditor,
Image,
StatusBar,
LayoutAnimation
} from "react-native";
import firebaseSvc from "../FirebaseSvc";
import firebase from "firebase";
import { auth, initializeApp, storage } from "firebase";
import uuid from "uuid";
class Login extends React.Component {
state = {
name: "",
email: "",
password: "",
avatar: ""
};
// using Fire.js
onPressLogin = async () => {
console.log("pressing login... email:" + this.state.email);
const user = {
name: this.state.name,
email: this.state.email,
password: this.state.password,
avatar: this.state.avatar
};
const response = firebaseSvc.login(
user,
this.loginSuccess,
this.loginFailed
);
};
loginSuccess = () => {
console.log("login successful, navigate to chat.");
this.props.navigation.navigate("TelaTeste", {
name: this.state.name,
email: this.state.email,
avatar: this.state.avatar
});
};
loginFailed = () => {
console.log("login failed ***");
alert("Login failure. Please tried again.");
};
onChangeTextEmail = email => this.setState({ email });
onChangeTextPassword = password => this.setState({ password });
render() {
LayoutAnimation.easeInEaseOut();
return (
<View style={styles.container}>
<KeyboardAvoidingView behavior="padding">
<Text style={styles.titulo}>{"CUDDLE"}</Text>
<View style={styles.errorMessage}>
{this.state.errorMessage && (
<Text style={styles.error}>{this.state.errorMessage}</Text>
)}
</View>
<View style={styles.form}>
<View>
<Text style={styles.inputTitle}>Email Address</Text>
<TextInput
style={styles.input}
autoCapitalize="none"
onChangeText={this.onChangeTextEmail}
value={this.state.email}
></TextInput>
</View>
<View style={{ marginTop: 32 }}>
<Text style={styles.inputTitle}>Password</Text>
<TextInput
style={styles.input}
secureTextEntry
autoCapitalize="none"
onChangeText={this.onChangeTextPassword}
value={this.state.password}
></TextInput>
</View>
</View>
<TouchableOpacity style={styles.button} onPress={this.onPressLogin}>
<Text style={{ color: "#FFF", fontWeight: "500" }}>Sign in</Text>
</TouchableOpacity>
<TouchableOpacity
style={{ alignSelf: "center", marginTop: 32 }}
onPress={() => this.props.navigation.navigate("Register")}
>
<Text style={{ color: "#414959", fontSize: 13 }}>
New to SocialApp?{" "}
<Text style={{ fontWeight: "500", color: "#5B2B80" }}>
Sign Up
</Text>
</Text>
</TouchableOpacity>
</KeyboardAvoidingView>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1
},
titulo: {
color: "#5B2B80",
fontSize: 30,
fontWeight: "bold",
textAlign: "center",
marginTop: 150
},
errorMessage: {
height: 72,
alignItems: "center",
justifyContent: "center",
marginHorizontal: 30
},
error: {
color: "#5B2B80",
fontSize: 13,
fontWeight: "600",
textAlign: "center"
},
form: {
marginBottom: 48,
marginHorizontal: 60
},
inputTitle: {
color: "#8A8F9E",
fontSize: 10,
textTransform: "uppercase"
},
input: {
borderBottomColor: "#8A8F9E",
borderBottomWidth: StyleSheet.hairlineWidth,
height: 40,
fontSize: 15,
color: "#161F3D"
},
button: {
marginHorizontal: 60,
backgroundColor: "#5B2B80",
borderRadius: 4,
height: 52,
alignItems: "center",
justifyContent: "center"
}
});
export default Login;
App.js
import Login from "./components/Login";
import CreateAccount from "./components/CreateAccount";
import Chat from "./components/Chat";
import TelaTeste from "./components/TelaTeste";
// Import React Navigation
import { createAppContainer } from "react-navigation";
import { createStackNavigator } from "react-navigation-stack";
const AppNavigator = createStackNavigator({
Login: { screen: Login },
CreateAccount: { screen: CreateAccount },
Chat: { screen: Chat },
TelaTeste: TelaTeste
});
export default createAppContainer(AppNavigator);
Change, to use arrow function, this inside user() refers to a different thing
get user() {
return {
name: this.props.navigation.state.params.name,
email: this.props.navigation.state.params.email,
avatar: this.props.navigation.state.params.avatar,
id: firebaseSvc.uid,
_id: firebaseSvc.uid // need for gifted-chat
};
}
to
user = () => {
return {
name: this.props.navigation.state.params.name,
email: this.props.navigation.state.params.email,
avatar: this.props.navigation.state.params.avatar,
id: firebaseSvc.uid,
_id: firebaseSvc.uid // need for gifted-chat
};
}
I want to navigate from Order screen To Home Screen but he doesn't work very well, every screen in the route is work, But Home screen Nope, Just back me to the Map screen, And I want Home Screen Not Map !! I already tell them to navigate to Home.
Here is structure I'm Dowing
Home -> Map -> Order, then Order -> Home
and in the Home, I have side menu Drawer check under the code.
Route.js
import React, { Component } from 'react';
import {
View,
TouchableOpacity,
} from 'react-native';
//Import required react-navigation component
import {
createDrawerNavigator,
createStackNavigator,
createAppContainer,
createSwitchNavigator
} from 'react-navigation';
//Import all the screens for Drawer/ Sidebar
import Home from "../screens/Home";
import Splash from "../screens/Splash";
import SignUp from "../screens/SignUp";
import SignIn from "../screens/SignIn";
import ForgetPassword from "../screens/ForgetPassword";
import Order from "../screens/Order";
import MapApp from "../screens/MapApp";
import Profile from "../screens/Profile";
import Icon from 'react-native-vector-icons/Ionicons';
//Navigation Drawer Structure for all screen
class NavigationDrawerStructure extends Component {
//Structure for the navigatin Drawer
toggleDrawer = () => {
//Props to open/close the drawer
this.props.navigationProps.toggleDrawer();
};
render() {
return (
<View style={{ flexDirection: 'row' }}>
<TouchableOpacity onPress={this.toggleDrawer.bind(this)}>
<Icon name="md-menu" size={30} color='#fff' style={{ marginLeft: 10 }} />
</TouchableOpacity>
</View>
);
}
}
// Stack Navigator for app
const AuthStackNavigator = createStackNavigator({
//All the screen from the Screen1 will be indexed here
SignUp: {
screen: SignUp,
navigationOptions: () => ({
// header: null
title: "Sign Up",
headerLeft: null,
headerTintColor: "#0496FF",
headerStyle: {
borderBottomColor: "white"
},
headerTitleStyle: {
color: "#0496FF",
textAlign: "center",
flex: 1,
elevation: 0,
fontSize: 25,
justifyContent: "center"
}
})
},
SignIn: {
screen: SignIn,
navigationOptions: {
title: "Sign In",
headerRight: <View />,
headerTintColor: "#0496FF",
headerStyle: {
borderBottomColor: "white"
},
headerTitleStyle: {
color: "#0496FF",
textAlign: "center",
flex: 1,
elevation: 0,
fontSize: 25,
justifyContent: "center"
}
}
},
ForgetPassword: {
screen: ForgetPassword,
navigationOptions: {
title: "Forget Password",
headerRight: <View />,
headerTintColor: "#0496FF",
headerStyle: {
borderBottomColor: "white"
},
headerTitleStyle: {
color: "#0496FF",
textAlign: "center",
flex: 1,
elevation: 0,
fontSize: 25,
justifyContent: "center"
}
}
},
});
//Stack Navigator for First Option of Navigation Drawer
const HomeDrawer = createStackNavigator({
Home: {
screen: Home,
navigationOptions: ({ navigation }) => ({
title: 'Home',
headerLeft: <NavigationDrawerStructure navigationProps={navigation} />,
headerRight: <View />,
headerStyle: {
backgroundColor: '#258fdb',
shadowOpacity: 0,
elevation: 0,
marginBottom: 20
},
headerTintColor: '#fff',
headerTitleStyle: {
textAlign: "center",
flex: 1,
elevation: 0,
fontSize: 25,
justifyContent: "center"
}
}),
},
MapApp: {
screen: MapApp,
navigationOptions: {
title: "Map",
headerRight: <View />,
headerLeft: <View />,
headerTintColor: "#fff",
headerStyle: {
backgroundColor: "#258fdb",
borderBottomColor: "white",
},
headerTitleStyle: {
textAlign: "center",
flex: 1,
elevation: 0,
fontSize: 25,
justifyContent: "center"
}
}
}
});
//Stack Navigator for Second Option of Navigation Drawer
const OrderDrawer = createStackNavigator({
Order: {
screen: Order,
navigationOptions: ({ navigation }) => ({
title: 'Order',
headerLeft: <NavigationDrawerStructure navigationProps={navigation} />,
headerStyle: {
backgroundColor: '#258fdb',
},
headerTintColor: '#fff',
}),
},
});
const ProfileDrawer = createStackNavigator({
Profile: {
screen: Profile,
navigationOptions: ({ navigation }) => ({
title: 'Profile',
headerLeft: <NavigationDrawerStructure navigationProps={navigation} />,
headerStyle: {
backgroundColor: '#258fdb',
},
headerTintColor: '#fff',
}),
},
})
//Drawer Navigator for the Navigation Drawer / Sidebar
const DrawerNavigator = createDrawerNavigator({
Home: {
screen: HomeDrawer,
navigationOptions: {
drawerLabel: 'Home',
drawerIcon: () => (
<Icon name="ios-home" size={30} color='#0496FF' />
),
},
},
Order: {
screen: OrderDrawer,
navigationOptions: {
drawerLabel: 'Order',
drawerIcon: () => (
<Icon name="ios-list-box" size={30} color='#0496FF' />
),
},
},
Profile: {
screen: ProfileDrawer,
navigationOptions: {
drawerLabel: 'Profile',
drawerIcon: () => (
<Icon name="ios-contact" size={30} color='#0496FF' />
),
},
},
});
const Navigations = createSwitchNavigator({
Authloading: Splash,
Auth: AuthStackNavigator, // the Auth stack
App: DrawerNavigator, // the App stack
})
export default MyApp = createAppContainer(Navigations);
Order.js
import React, { Component } from 'react';
import styles from "../Style/styles";
import firebase from "react-native-firebase";
import ImagePicker from "react-native-image-picker";
import { View, Text, StyleSheet, TextInput, ScrollView, KeyboardAvoidingView, TouchableOpacity, Image } from 'react-native';
// create a component
class Order extends Component {
constructor(props) {
super(props);
this.state = {
userId: null,
nameOfProblem: '',
description: '',
imageOfPrblem: '',
timeDate: {},
providerId: this.props.navigation.dangerouslyGetParent().getParam('providerId'),
}
}
componentDidMount() {
const userId = firebase.auth().currentUser.uid;
this.setState({ userId });
}
handleOrder = () => {
const { nameOfProblem, description, userId, imageOfPrblem, providerId } = this.state;
const PushData = firebase.database().ref("request/" + providerId + "/" + userId + "/orders/");
const ref = firebase.storage().ref("users/" + userId + "/UserImageOrders/" + path);
let file = imageOfPrblem.uri;
const path = "img_" + imageOfPrblem.fileName;
if (file) {
return (
PushData.update({
nameOfProblem: nameOfProblem,
description: description,
// ...this.state.nameOfProblem,
// ...this.state.description,
imageOfPrblem: imageOfPrblem
}).then(() => {
ref.put(file).then(() => {
console.log("File uploaded..")
setTimeout(() => {
this.props.navigation.navigate("Home"); // not working and get me back to Map screen, but when i navigate to other screen it's work fine!
}, 3000);
});
})
)
}
else {
return (
PushData.push({
nameOfProblem: nameOfProblem,
description: description,
}).then(() => {
setTimeout(() => {
this.props.navigation.navigate("Home"); // Not work
}, 3000);
})
)
}
// else {
// }
}
handleImages = () => {
const options = {
title: "Select Images!",
storageOptions: {
skipBackup: true,
path: "images"
}
};
ImagePicker.showImagePicker(options, response => {
console.log("Response = ", response);
if (response.uri) {
this.setState({ imageOfPrblem: response });
}
if (response.didCancel) {
console.log("User cancelled image picker");
} else if (response.error) {
console.log("ImagePicker Error: ", response.error);
} else if (response.customButton) {
console.log("User tapped custom button: ", response.customButton);
alert(response.customButton);
}
});
};
render() {
const { nameOfProblem, description, imageOfPrblem, timeDate } = this.state;
const { getParam } = this.props.navigation.dangerouslyGetParent();
const providerId = getParam('providerId');
const providerName = getParam('providerName');
return (
<ScrollView scrollEnabled={true}>
<KeyboardAvoidingView behavior="padding" keyboardVerticalOffset={70}>
<View style={[styles.container, { marginTop: 20 }]}>
<Text>Send Order To: {JSON.stringify(providerName)}, ID:{JSON.stringify(providerId)}</Text>
<TextInput
style={styles.textInput}
placeholder="Name of Problem"
value={nameOfProblem}
onChangeText={(nameOfProblem) => this.setState({ nameOfProblem })}
returnKeyType="next"
returnKeyLabel="next"
/>
<TextInput
style={[styles.textInput, {
borderRadius: 5,
borderWidth: 1,
height: 120,
fontSize: 16,
padding: 10,
marginTop: 8
}]}
placeholder="Description"
multiline={true}
numberOfLines={12}
textAlignVertical="top"
value={description}
onChangeText={(description) => this.setState({ description })}
returnKeyType="next"
returnKeyLabel="next"
/>
<TouchableOpacity onPress={this.handleImages}>
<View
style={{
backgroundColor: "#DBDBDB",
borderRadius: 100,
alignSelf: "center",
margin: 10,
paddingBottom: 2,
width: 120,
height: 120
}}
>
<Text
style={{
position: "absolute",
zIndex: 1,
fontSize: 40,
top: 67,
color: "#1567d3",
left: 99
}}
>
+
</Text>
<Image
source={{ uri: imageOfPrblem.uri }}
style={[styles.uploadAvatar, { borderRadius: 100 }]}
resizeMode="cover"
/>
</View>
</TouchableOpacity>
<TouchableOpacity
style={[styles.button, { backgroundColor: "#1567d3" }]}
onPress={this.handleOrder}
>
<Text style={{ color: "#fff", fontSize: 18 }}>Send</Text>
</TouchableOpacity>
</View>
</KeyboardAvoidingView>
</ScrollView>
);
}
}
// define your styles
//make this component available to the app
export default Order;
You have two routes with the name "Home", one in HomeDrawer and one in DrawerNavigator. Rename the one in DrawerNavigator and it should navigate to the correct "Home".
For example:
HomeDrawer: { // renamed this from Home to HomeDrawer
screen: HomeDrawer,
navigationOptions: {
drawerLabel: 'Home',
drawerIcon: () => (
<Icon name="ios-home" size={30} color='#0496FF' />
),
},
},
When exporting Home.js, export it like this (using withNavigation ).
import React, { Component } from 'react'
import { Text, View } from 'react-native'
import { withNavigation } from 'react-navigation';
class Home extends Component {
render() {
return (
<View>
<Text> Home </Text>
</View>
)
}
}
export default withNavigation(Home);
I'm having trouble accessing this.state in functions inside my component.
Always I get "Undefined is not a object this.state.username, this.state.password" error
SimpleForm.js
import Expo from 'expo';
import React from 'react';
import { StackNavigator, DrawerNavigator } from 'react-navigation';
import App from './App';
import RegisterForm from './register';
import { View, Text, TextInput, Image, TouchableOpacity, AsyncStorage, StyleSheet } from 'react-native';
import { YourRestApi } from './constants/api3';
class SimpleForm extends React.Component {
constructor(props) {
super(props);
this.state = { username: '', password: '', datas: '' };
this.login = this.login.bind(this, this.state.username, this.state.password);
}
componentWillMount() {
this.login();
}
registerscreen = () => {
this.props.navigation.navigate('Register');
}
login() {
YourRestApi(this.state.username, this.state.password)
.then((response) => {
console.log(response.success);
this.setState({ loading: false, datas: response });
});
if (this.state.datas.success === true) {
const info = this.state.datas.message;
AsyncStorage.setItem('info', JSON.stringify(info));
this.props.navigation.navigate('SecondScreen');
} else {
alert(this.state.datas.message);
}
}
render() {
const { navigate } = this.props.navigation;
return (
<View style={styles.container}>
<Image source={require('./assets/img/sd.png')} style={styles.backgroundImage}>
<View style={styles.content}>
<Text style={styles.logo}>Toto Prediction </Text>
<View style={styles.inputContainer}>
<TextInput
underlineColorAndroid='transparent' style={styles.input}
onChangeText={(username) => this.setState({ username })}
value={this.state.username} placeholder='username'
/>
<TextInput
secureTextEntry underlineColorAndroid='transparent' style={styles.input}
onChangeText={(password) => this.setState({ password })}
value={this.state.password} placeholder='password'
/>
</View>
<TouchableOpacity onPress={this.login} style={styles.buttonContainer}>
<Text style={styles.buttonText}>Login</Text>
</TouchableOpacity>
this._onPressGet.bind(this)
<TouchableOpacity onPress={this.registerscreen} style={styles.buttonContainer}>
<Text style={styles.buttonText}>Register</Text>
</TouchableOpacity>
</View>
</Image>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
backgroundImage: {
flex: 1,
alignSelf: 'stretch',
width: null,
justifyContent: 'center',
},
content: {
alignItems: 'center',
},
logo: {
color: 'white',
fontSize: 40,
fontStyle: 'italic',
fontWeight: 'bold',
textShadowColor: '#252525',
textShadowOffset: { width: 2, height: 2 },
textShadowRadius: 15,
marginBottom: 20,
},
inputContainer: {
margin: 20,
marginBottom: 0,
padding: 20,
paddingBottom: 10,
alignSelf: 'stretch',
borderWidth: 1,
borderColor: '#fff',
backgroundColor: 'rgba(255,255,255,0.2)',
},
input: {
fontSize: 16,
height: 40,
padding: 10,
marginBottom: 10,
backgroundColor: 'rgba(255,255,255,1)',
},
buttonContainer: {
margin: 20,
padding: 20,
backgroundColor: 'blue',
borderWidth: 1,
borderColor: '#fff',
backgroundColor: 'rgba(255,255,255,0.6)',
},
buttonText: {
fontSize: 16,
fontWeight: 'bold',
textAlign: 'center',
},
});
const SimpleApp = DrawerNavigator({
Onescreen: { screen: SimpleForm },
SecondScreen: { screen: App },
Register: { screen: RegisterForm },
});
Expo.registerRootComponent(SimpleApp);
Api3.js
export function YourRestApi(username1, password1) {
fetchlogin(username1, password1);
}
function fetchlogin(username1, password1) {
const details = {
username: username1,
password: password1,
};
const formBody = Object.keys(details).map(key => `${encodeURIComponent(key)}=${encodeURIComponent(details[key])}`).join('&');
fetch('https://*********************', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
},
body: formBody,
})
.then((response) => response.json())
.then((response) => {
console.log('requestAppInstallation success ', response);
return response;
})
.done();
}
I tried binding login to this.state but doesnt worked
I already checked other questions but nothing is worked
Any idea what could be causing this ?
In your constructor replace the binding statement like below
constructor(props) {
super(props);
this.state = { username: '', password: '', datas: '' };
this.login = this.login.bind(this);
}
Your login function should be bound in order for it to access the correct this if passed to a Touchable.
Could be fixed by either one of these ways:
<TouchableOpacity onPress={this.login.bind(this)} ...>
OR:
<TouchableOpacity onPress={() => this.login()} ...>
It is basically nothing but just an error returned by firebase in case user enters wrongly formatted email. Try entering rightly formatted email id in the signup or login form and you will not get that error from firebase.
Firebase basically checks at its end whether user entered correct mail id or not while creating new user.