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.
Related
is anyone able to help pass the data to the modal? The .map function returns the month names from the data [] array (needed for the slider), and I'd like to display that particular one in a modal view as well.
Current view:
and modal:
expectations:
unfortunately, only the first month from the [] is visible in the modal.
I am also putting the .js file for review:
import React, { useContext, useState } from 'react';
import { AuthenticatedUserContext } from '../AuthenticatedUserProvider';
import { Swiper } from 'react-native-swiper';
import Modal from 'react-native-modal';
import { db } from '../firebase';
import FontAwesome from 'react-native-vector-icons/FontAwesome';
import { View, Text, TouchableHighlight, StyleSheet, Button, TextInput, TouchableOpacity } from 'react-native';
const data = [
{ id: 1, name: 'Month1' },
{ id: 2, name: 'Month2' },
{ id: 3, name: 'Month3' }
];
export default function HomeScreen() {
const { user } = useContext(AuthenticatedUserContext);
const [ isModalVisible, setModalVisible ] = useState(false);
const [ months, setMonths ] = useState(data);
const [ values, setValues ] = useState({
budget: '',
month: '',
});
const toggleModal = () => {
setModalVisible(!isModalVisible);
};
const onSave = () => {
setValues({ ...values, userId: user.uid });
setModalVisible(!isModalVisible);
db.collection('Budget').add({
userId: user.uid,
budget: values.budget,
});
};
return (
<Swiper showsButtons={true} showsPagination={false} buttonWrapperStyle={{ alignItems: 'flex-start' }}>
{months.map((months, i) => (
<View key={i} style={styles.slider}>
<Text style={styles.text}> {months.name}</Text>
<View>
<View style={styles.mainCardView}>
<TouchableOpacity
onPress={
toggleModal
}
style={{ flex: 1, alignItems: 'flex-end', marginTop: 20 }}
>
<FontAwesome name="pencil-square-o" color="black" size={30} />
</TouchableOpacity>
</View>
</View>
<Modal isVisible={isModalVisible} style={{ margin: 0 }}>
<Text style= {{marginLeft: 50, color: '#fff'}}>Current month: {months.name}</Text>
<TextInput
style={{
height: 40,
borderColor: 'white',
borderWidth: 1,
color: 'white',
shadowColor: 'white',
margin: 50,
padding: 5,
marginVertical: 10,
}}
onChange={(e) => setValues({ ...values, budget: e.target.value })}
value={values.budget}
placeholder="Budget"
keyboardType="decimal-pad"
placeholderTextColor="#fff"
/>
<TouchableHighlight
style={{
height: 40,
borderRadius: 10,
backgroundColor: 'gray',
marginLeft: 50,
marginRight: 50,
marginTop: 20,
}}
>
<Button
onPress={onSave}
title="Confirm"
/>
</TouchableHighlight>
<TouchableHighlight
style={{
height: 40,
borderRadius: 10,
backgroundColor: 'gray',
marginLeft: 50,
marginRight: 50,
marginTop: 20,
}}
>
<Button
onPress={toggleModal}
title="Back"
/>
</TouchableHighlight>
</Modal>
</View>
))}
</Swiper>
);
}
Here are a couple suggestions:
{months.map((months, i) => (...))} I would not recommend using months as the current item in the map since its confusing. Instead, I would recommend something like months.map((month, i) => ())} since in actuality you are referring to just one month within the map.
You are rendering the modal within your map, so each month has its own modal. But you only render one modal at a time, so instead you can just put the modal outside of the map, and somehow point the modal to the currently active month (see below)
If you have another piece of state like const [activeMonth, setActiveMonth] = useState(). Then when you click one of the months you can set the modal state to open, and set the activeMonth state. Then in the modal, it would just display state based off the current active month. It seems like you can make use of your values state to do that probably!
I have this code, where on ChangeText in react native, i am inserting multiple field values in the state, item. For some reason, the output in the console log shows alphabetical order. Since the logic is, that on ChangText, the function EnterValue inserts the value in item state. it finds the property name and then matches that to the text value, I think something gets wrong along the way. Please see below the code
import { StatusBar } from "expo-status-bar";
import React from "react";
import { StyleSheet, Text, View, Button, TextInput } from "react-native";
class App extends React.Component {
constructor() {
super();
this.state = {
step: 1,
TotalItem: [],
item: {
Brand: null,
Quantity: null,
Instructions: null,
},
};
}
// remember this logig since take names, it adds property values in alphabetical order, and thus change the order
EnterValue = (name) => {
return (text) => {
this.setState((prevState) => ({
item: { ...prevState.item, [name]: text },
}));
};
};
submit = (e) => {
e.preventDefault(e);
const { step } = this.state;
this.setState({
step: step + 1,
});
this.setState(
{
TotalItem: [...this.state.TotalItem, this.state.item],
},
() => {
console.log("updated state", this.state.TotalItem);
}
);
};
render() {
return (
<View style={{ flex: 1, margin: 20 }}>
<TextInput
placeholder="enter name"
onChangeText={this.EnterValue("Brand")}
style={{ borderWidth: 2, borderColor: "skyblue", margin: 20 }}
/>
<TextInput
placeholder="Quantity"
onChangeText={this.EnterValue("Quantity")}
style={{ borderWidth: 2, borderColor: "skyblue", margin: 20 }}
/>
<TextInput
placeholder="Instructions"
onChangeText={this.EnterValue("Instructions")}
style={{ borderWidth: 2, borderColor: "skyblue", margin: 20 }}
/>
<View style={styles.container}>
<View style={{ flex: 1 }}>
<Button
style={{ flex: 1, backgroundColor: "red" }}
title="add"
onPress={this.add}
/>
</View>
<View style={{ flex: 1 }}>
<Button
style={{ flex: 1, backgroundColor: "blue" }}
title="submit"
onPress={this.submit}
/>
</View>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flexDirection: "row",
alignItems: "center",
justifyContent: "center",
},
});
export default App;
Change
onChangeText={this.EnterValue("Quantity")}
onChangeText={this.EnterValue("Brand")}
onChangeText={this.EnterValue("Instructions ")}
To
onChangeText={() => this.EnterValue("Quantity")}
onChangeText={() => this.EnterValue("Brand")}
onChangeText={() => this.EnterValue("Instructions ")}
I'm trying to add a new subobject to an existing object using the method this.setState in a expo application. The subobject are added after a click of a button, that update the fields that compons the subobject.
This is my code:
import React, { Component } from 'react';
import { View, Text, StyleSheet, TouchableOpacity, ImageBackground } from 'react-native';
import CenteredButton from '../components/CenteredButton';
import { Actions } from 'react-native-router-flux';
var t = require('tcomb-form-native');
var _ = require('lodash');
const Form = t.form.Form;
const stylesheet = _.cloneDeep(t.form.Form.stylesheet);
stylesheet.textbox.normal.borderColor = '#b3b3b5';
stylesheet.textbox.normal.fontFamily = 'RobotoThin';
stylesheet.textbox.normal.backgroundColor = '#fdfdfd';
stylesheet.textbox.normal.fontSize = 18;
stylesheet.textbox.normal.borderWidth = 0.6;
stylesheet.textbox.normal.borderRadius = 10;
stylesheet.textbox.error.fontFamily = 'RobotoThin';
stylesheet.textbox.error.backgroundColor = '#fdfdfd';
stylesheet.textbox.error.fontSize = 18;
stylesheet.textbox.error.borderWidth = 0.6;
stylesheet.textbox.error.borderRadius = 10;
const Email = t.refinement(t.String, email => {
const regex = /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*#(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/;
return regex.test(email);
});
const EmailTo = t.struct({
emailPerson: Email,
emailInsurance: t.maybe(Email)
});
const options = {
auto: 'none',
stylesheet: stylesheet,
fields: {
emailPerson: {
placeholder: 'Email personale',
autoCapitalize: 'none',
autoCorrect: false,
},
emailInsurance: {
placeholder: 'Email Assicurazione',
autoCapitalize: 'none',
password: true,
}
}
}
export default class NessunProblema extends Component {
constructor(props) {
super(props);
this.state = {
emails: {
emailPerson: '',
emailInsurance: ''
},
ascertainment: { }
}
}
componentDidMount() {
this.setState({ ascertainment: this.props.ascertainment });
}
_onChange = (emails) => {
this.setState({ emails });
}
_handle = () => {
const value = this.refs.form.getValue();
if ( value ) {
this.setState(prev => ({
ascertainment: {
...prev.ascertainment,
emails: {
...prev.ascertainment.emails,
emailPerson: value.emailPerson,
emailInsurance: value.emailInsurance
}
}
}));
}
console.log(this.state.emails);
console.log(this.state.ascertainment);
}
render() {
return (
<View style={{flex: 1, backgroundColor: 'white' }}>
<ImageBackground source={require('../images/NoProblem.png')} style={styles.backgroundImage}>
<View style={{ flex: 2, alignItems: 'center', justifyContent: 'center', width: '100%', paddingHorizontal: 20, top: 10}}>
<Text style={styles.domanda}>
Text
</Text>
<Text style={styles.domanda2}>
Text
</Text>
</View>
<View style={{padding: 20}}>
<Form
ref='form'
options={options}
type={EmailTo}
value={this.state.emails}
onChange={this._onChange}
/>
</View>
<CenteredButton
next={ this._handle }
/>
</ImageBackground>
</View>
)
}
}
const styles = StyleSheet.create({
domanda: {
color: '#00b0ff',
textAlign: 'center',
fontSize: 44,
fontFamily: 'RobotoRegular',
alignItems: 'center',
justifyContent: 'center',
padding: 20
},
domanda2: {
color: 'black',
textAlign: 'center',
fontSize: 22,
fontFamily: 'RobotoRegular',
alignItems: 'center',
justifyContent: 'center',
padding: 20
},
testoRosso: {
color: '#f32a19',
fontFamily: 'RobotoRegular',
},
backgroundImage: {
flex: 1,
resizeMode: 'cover'
},
textInput: {
width: '100%',
paddingHorizontal: 15,
height: 40,
marginBottom: 20,
fontSize: 18,
borderWidth: 0.6,
borderColor: 'black',
borderRadius: 10,
color: 'black',
fontFamily: 'RobotoThin',
backgroundColor: 'white'
},
});
I noticed that, if I click TWO times the button AVANTI I obtein the correct result. But, WHY?
I follow this answer but doens't resolve the problem.
The problem is that setState() is not synchronous, the values are updated asynchronously
setState() does not immediately mutate this.state but creates a pending state transition. Accessing this.state after calling this method can potentially return the existing value. There is no guarantee of synchronous operation of calls to setState and calls may be batched for performance gains.
_handle = () => {
const value = this.refs.form.getValue();
if ( value ) {
this.setState(prev => ({
ascertainment: {
...prev.ascertainment,
emails: {
...prev.ascertainment.emails,
emailPerson: value.emailPerson,
emailInsurance: value.emailInsurance
}
}
}));
}
console.log(this.state.emails); // will be the emails in the previous state, since setState has not been called yet by react
console.log(this.state.ascertainment); // if you click twice, you are still getting the `last` state, but since it is the same as the state you are setting the second time, you get the wrong idea that it is being set if you click twice!
}
I have searched the whole web to the best of my ability on how to create an interface for selecting products just like the ones implemented in most of the major e-commerce apps(amazon,taobao,shopify..).The goal is to highlight or change the styles of the selected item in the list by simultaneously removing the styles of the previously selected item. I am trying to use react-native to clone such a feature. Any references or guides on how to do this will be highly appreciated!
import React, { Component } from 'react';
import { View, Text ,StyleSheet, TouchableOpacity, } from 'react-native';
class Selections extends Component {
state={
highlighted: false,
id: null
}
// The purpose of this function is to set the state to the target index on press
indexStateHandler = (i) =>{
if(this.state.id === null){
this.setState({
id: i
})
}else{
this.setState({
id:i
})
}
console.log("index: "+i)
console.log("state: "+this.state.id)
}
//The purpose of this function is to set styles for the targeted index
highlightStateHandler = (i) =>{
if(this.state.id === i){
if(!this.state.highlighted){
this.setState({
highlighted:true
})
}
else{
this.setState({
highlighted:false
})
}
}
}
highlightHandler = (i) =>{
// console.log(i)
this.indexStateHandler(i)
this.highlightStateHandler(i)
}
render() {
return (
<View style={styles.selectionWrapper}>
<View style={styles.label}><Text style={{color: "black"}}>{this.props.label}</Text></View>
<View style={styles.listContainer}>
{this.props.options.map((options, i) => (
<TouchableOpacity onPress={()=>this.highlightHandler(i)} key={i}>
<View style={this.state.highlighted&&this.state.id == i?styles.highlighted:styles.options} > <Text style={styles.text}>{options}</Text> </View>
</TouchableOpacity>
)
)}
</View>
</View>
);
}
}
const styles= StyleSheet.create({
selectionWrapper:{
width: '100%',
height: 100,
borderWidth: 1,
borderColor: 'red',
},
label:{
flex: 1,
}
,
listContainer:{
flex: 3,
flexDirection: "row",
justifyContent: "space-around",
alignItems: 'center',
// backgroundColor: "#7fffd4"
},
options:{
borderRadius: 10,
padding: 5,
borderWidth: 1,
borderColor: "#d0b783",
// backgroundColor: ""
},
text:{
color: 'black',
textAlign: 'center'
},
highlighted:{
borderRadius: 10,
padding: 5,
borderWidth: 1,
// borderColor: "#d0b783",
backgroundColor: "#d0b783"
}
})
export default Selections
.....
.....
.....
<TouchableOpacity
style={[styles.buttonStyle,{
backgroundColor : item.id === this.state.selectedItem.id ? "red" : "blue"
}]}
>
{
...
...
}
</TouchableOpacity>
.....
.....
.....
Have a look on TouchableOpacity and TouchableHighlight and try to run examples to see how they work. Also you can combine them to changing visual changes by changing styles.
import React, { Component } from 'react' import { AppRegistry, StyleSheet, TouchableOpacity, Text, View, } from 'react-native'
export default class App extends React.Component { constructor(props) {
super(props)
this.state = {
itemEn1: true,
itemEn2: false,
itemEn3: false,
} }
onPress1 = () => {
this.setState({
itemEn1: true,
itemEn2: false,
itemEn3: false,
}) }
onPress2 = () => {
this.setState({
itemEn1: false,
itemEn2: true,
itemEn3: false,
}) }
onPress3 = () => {
this.setState({
itemEn1: false,
itemEn2: false,
itemEn3: true,
}) }
render() {
return (
<View style={styles.container}>
<TouchableOpacity
style={this.state.itemEn1 ? styles.buttonEnabled : styles.buttonDisabled}
onPress={this.onPress1}>
<Text> Item 1 </Text>
</TouchableOpacity>
<TouchableOpacity
style={this.state.itemEn2 ? styles.buttonEnabled : styles.buttonDisabled}
onPress={this.onPress2}>
<Text> Item 2 </Text>
</TouchableOpacity>
<TouchableOpacity
style={this.state.itemEn3 ? styles.buttonEnabled : styles.buttonDisabled}
onPress={this.onPress3}>
<Text> Item 3 </Text>
</TouchableOpacity>
</View>
) } }
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingHorizontal: 10
},
buttonDisabled: {
alignItems: 'center',
backgroundColor: '#DDDDDD',
padding: 10,
marginTop: 20
},
buttonEnabled: {
alignItems: 'center',
backgroundColor: 'green',
padding: 10,
marginTop: 20
},
countContainer: {
alignItems: 'center',
padding: 10
},
})
this is by map function:
export default class DataCollector extends React.Component {
constructor(props) {
super(props);
this.SendBack = this.SendBack.bind(this);
}
SendBack(info) {
console.log("Key is :", info);
this.props.callback(info);
}
render() {
let testData = this.props.data.map(function (articleData, index) {
return (
<View key={index}>
<TouchableOpacity
activeOpacity={0.6}
key={index}
onPress={() => this.callBack([articleData.id, articleData.name])}>
</TouchableOpacity>
</View>
)
}, this);
return (
<View>
{testData}
</View>
);
}
}
so now you have access to the clicked item and can use it for enable/disable etc..
I am trying to follow the example (https://github.com/facebook/react-native/tree/master/Examples/UIExplorer/Navigator) on the react native site to set up my navigator, but I can't seem to get it to work. No matter what I seem to do, the GoogSignIn scene always comes up blank although it does hit both of my console.log points in the file. I have tried switching the starting point to a different scene in my app, but the same thing always happens. I assume this is something I did wrong in index.ios.js with my navigator, but I'm not sure what. Any help is much appreciated.
index.ios.js
'use strict';
var React = require('react-native');
var DataEntry = require('./app/DataEntry');
var PasswordView = require('./app/PasswordView');
var GoogSignIn = require('./app/GoogSignIn');
var {
AppRegistry,
Image,
StyleSheet,
Text,
View,
Navigator,
TouchableOpacity,
} = React;
class PasswordRecovery extends React.Component {
render() {
return (
<Navigator
ref={this._setNavigatorRef}
style={styles.container}
initialRoute={{id: 'GoogSignIn', name: 'Index'}}
renderScene={this.renderScene}
configureScene={(route) => {
if (route.sceneConfig) {
return route.sceneConfig;
}
return Navigator.SceneConfigs.FloatFromRight;
}} />
);
}
renderScene(route, navigator) {
switch (route.id) {
case 'GoogSignIn':
return <GoogSignIn navigator={navigator} />;
case 'DataEntry':
return <DataEntry navigator={navigator} />;
case 'PasswordView':
return <PasswordView navigator={navigator} />;
default:
return this.noRoute(navigator);
}
noRoute(navigator) {
return (
<View style={{flex: 1, alignItems: 'stretch', justifyContent: 'center'}}>
<TouchableOpacity style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}
onPress={() => navigator.pop()}>
<Text style={{color: 'red', fontWeight: 'bold'}}>ERROR: NO ROUTE DETECTED</Text>
</TouchableOpacity>
</View>
);
}
_setNavigatorRef(navigator) {
if (navigator !== this._navigator) {
this._navigator = navigator;
if (navigator) {
var callback = (event) => {
console.log(
`TabBarExample: event ${event.type}`,
{
route: JSON.stringify(event.data.route),
target: event.target,
type: event.type,
}
);
};
// Observe focus change events from the owner.
this._listeners = [
navigator.navigationContext.addListener('willfocus', callback),
navigator.navigationContext.addListener('didfocus', callback),
];
}
}
}
componentWillUnmount() {
this._listeners && this._listeners.forEach(listener => listener.remove());
}
}
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});
AppRegistry.registerComponent('PasswordRecovery', () => PasswordRecovery);
I am just trying to get this all setup so that I can display a Google Sign in scene and then navigate from there. The code for that scene so far is here:
GoogSignIn.js
'use strict';
var React = require('react-native');
var { NativeAppEventEmitter } = require('react-native');
var GoogleSignin = require('react-native-google-signin');
var cssVar = require('cssVar');
var { Icon } = require('react-native-icons');
var {
AppRegistry,
StyleSheet,
Text,
View,
TouchableOpacity,
TouchableHighlight,
PixelRatio,
Navigator,
} = React;
var NavigationBarRouteMapper = {
LeftButton: function(route, navigator, index, navState) {
if (index === 0) {
return null;
}
var previousRoute = navState.routeStack[index - 1];
return (
<TouchableOpacity
onPress={() => navigator.pop()}
style={styles.navBarLeftButton}>
<Text style={[styles.navBarText, styles.navBarButtonText]}>
{previousRoute.title}
</Text>
</TouchableOpacity>
);
},
RightButton: function(route, navigator, index, navState) {
return (
null
);
},
Title: function(route, navigator, index, navState) {
return (
<Text style={[styles.navBarText, styles.navBarTitleText]}>
GOOGLE SIGN IN
</Text>
);
},
};
class GoogSignin extends React.Component {
constructor(props) {
super(props);
this.state = {
user: null
};
}
componentWillMount() {
var navigator = this.props.navigator;
var callback = (event) => {
console.log(
`NavigationBarSample : event ${event.type}`,
{
route: JSON.stringify(event.data.route),
target: event.target,
type: event.type,
}
);
};
// Observe focus change events from this component.
this._listeners = [
navigator.navigationContext.addListener('willfocus', callback),
navigator.navigationContext.addListener('didfocus', callback),
];
}
componentWillUnmount() {
this._listeners && this._listeners.forEach(listener => listener.remove());
}
componentDidMount() {
this._configureOauth(
'105558473349-7usegucirv10bruohtogd0qtuul3kkhn.apps.googleusercontent.com'
);
}
renderScene(route, navigator) {
console.log("HERE");
return (
<View style={styles.container}>
<TouchableHighlight onPress={() => {this._signIn(); }}>
<View style={{backgroundColor: '#f44336', flexDirection: 'row'}}>
<View style={{padding: 12, borderWidth: 1/2, borderColor: 'transparent', borderRightColor: 'white'}}>
<Icon
name='ion|social-googleplus'
size={24}
color='white'
style={{width: 24, height: 24}}
/>
</View>
<Text style={{color: 'white', padding: 12, marginTop: 2, fontWeight: 'bold'}}>Sign in with Google</Text>
</View>
</TouchableHighlight>
</View>
);
}
render() {
return (
<Navigator
debugOverlay={false}
style={styles.container}
renderScene={this.renderScene}
navigationBar={
<Navigator.NavigationBar
routeMapper={NavigationBarRouteMapper}
style={styles.navBar}/>
}/>
);
}
_configureOauth(clientId, scopes=[]) {
console.log("WE HERE")
GoogleSignin.configure(clientId, scopes);
NativeAppEventEmitter.addListener('googleSignInError', (error) => {
console.log('ERROR signin in', error);
});
NativeAppEventEmitter.addListener('googleSignIn', (user) => {
console.log(user);
this.setState({user: user});
});
return true;
}
_signIn() {
GoogleSignin.signIn();
}
_signOut() {
GoogleSignin.signOut();
this.setState({user: null});
}
};
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
messageText: {
fontSize: 17,
fontWeight: '500',
padding: 15,
marginTop: 50,
marginLeft: 15,
},
button: {
backgroundColor: 'white',
padding: 15,
borderBottomWidth: 1 / PixelRatio.get(),
borderBottomColor: '#CDCDCD',
},
buttonText: {
fontSize: 17,
fontWeight: '500',
},
navBar: {
backgroundColor: 'white',
},
navBarText: {
fontSize: 16,
marginVertical: 10,
},
navBarTitleText: {
color: cssVar('fbui-bluegray-60'),
fontWeight: '500',
marginVertical: 9,
},
navBarLeftButton: {
paddingLeft: 10,
},
navBarRightButton: {
paddingRight: 10,
},
navBarButtonText: {
color: cssVar('fbui-accent-blue'),
},
scene: {
flex: 1,
paddingTop: 20,
backgroundColor: '#EAEAEA',
},
});
module.exports = GoogSignin;
edit: screenshots of inspector:
In your renderScene method, try doing something like this (this will also help you remove that big switch):
Component = route.id
<View style={styles.container}>
<Component navigator={navigator} route={route} />
</View>
styles = StyleSheet.create({
container:
flex: 1
})