Skip to content

Instantly share code, notes, and snippets.

@monmanuela
Last active December 9, 2018 20:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save monmanuela/84d2ba61048773952fbf3629726503eb to your computer and use it in GitHub Desktop.
Save monmanuela/84d2ba61048773952fbf3629726503eb to your computer and use it in GitHub Desktop.
Code snippets from my Orbital project, "Lapar"

Lapar

These code snippets are from my Orbital project, "Lapar" [https://github.com/monmanuela/lapar/tree/redux]. I was mostly in charge of integrating Firebase and Redux into the app. I am proud of the code because:

  • Integrating Redux cleans the messy passing down of props to children components. Thus, components irrelevant to the props will not need to be aware of them. This reduces coupling, improving the maintainability.
  • Integrating Firebase gives the benefit of using well tested APIs to handle user authentication in a secure way, and also storage. The APIs allow us to abstract away the details and focus more on the core functionalities of the app.
import firebase from 'react-native-firebase'
// action types
export const UPDATE_LOCATION = 'UPDATE_LOCATION'
export const UPDATE_PREFERENCE = 'UPDATE_PREFERENCE'
export const LOG_IN_START = 'LOG_IN_START'
export const LOG_IN_SUCCESS = 'LOG_IN_SUCCESS'
export const LOG_IN_FAIL = 'LOG_IN_FAIL'
export const SIGN_UP_START = 'SIGN_UP_START'
export const SIGN_UP_SUCCESS = 'SIGN_UP_SUCCESS'
export const SIGN_UP_FAIL = 'SIGN_UP_FAIL'
export const LOG_OUT_SUCCESS = 'LOG_OUT_SUCCESS'
export const SET_USER_DATA = 'SET_USER_DATA'
export const UPDATE_USER_FROM_FIREBASE_LISTENER = 'UPDATE_USER_FROM_FIREBASE_LISTENER'
// other constants
export const NORMAL = 'NORMAL'
export const STALL = 'STALL'
// action creators
export const updateLocation = locations => {
return({
type: UPDATE_LOCATION,
payload: locations
})
}
export const updatePreferences = pref => {
return({
type: UPDATE_PREFERENCE,
payload: pref
})
}
export const updateUserFromFirebaseListener = user => {
console.log("update user from firebase listener")
console.log("the user: " + JSON.stringify(user))
return({
type: UPDATE_USER_FROM_FIREBASE_LISTENER,
payload: user
})
}
export const logOutUser = () => {
return({
type: LOG_OUT_SUCCESS,
})
}
export const indicateSignUpStall = () => {
return({
type: SIGN_UP_START,
payload: STALL
})
}
export const indicateSignUpNormal = () => {
return({
type: SIGN_UP_START,
payload: NORMAL
})
}
export const setUserData = data => {
return({
type: SET_USER_DATA,
payload: data
})
}
// async action creators
export const updateUserIfLoggedIn = user => async dispatch => {
try {
dispatch(updateUserFromFirebaseListener(user))
const userData = await fetchUserData(user.uid)
dispatch(setUserData(userData))
} catch (err) {
console.log(err)
}
}
export const updateUserIfNewSignUp = user => async dispatch => {
try {
dispatch(updateUserFromFirebaseListener(user))
// const userData = await fetchUserData(user.uid)
// dispatch({type: SET_USER_DATA, payload: userData})
} catch (err) {
console.log(err)
}
}
export const logInUser = (email, password) => async dispatch => {
if (email.length === 0 || password.length === 0) {
dispatch({type: LOG_IN_FAIL, payload: {errCode: 404, errMessage: "Email or password cannot be empty"}})
return;
}
dispatch({type: LOG_IN_START})
try {
const result = await firebase.auth().signInAndRetrieveDataWithEmailAndPassword(email, password)
const currentUser = result.user
dispatch({type: LOG_IN_SUCCESS, payload: currentUser})
const userData = await fetchUserData(currentUser.uid)
dispatch({type: SET_USER_DATA, payload: userData})
} catch (err) {
dispatch({type: LOG_IN_FAIL, payload: {errMessage: err.message}})
}
}
export const signUpUser = (email, password, displayName) => async dispatch => {
if (email.length === 0 || password.length === 0 || displayName.length === 0) {
dispatch({type: SIGN_UP_FAIL, payload: {errMessage: "Email, password or display name cannot be empty"}})
return;
}
dispatch(indicateSignUpNormal())
try {
// dispatch action to tell that this is Normal User
const result = await firebaseSignUpUser(email, password, displayName)
console.log("sign up result: " + JSON.stringify(result))
dispatch({type: SIGN_UP_SUCCESS, payload: result})
dispatch({type: SET_USER_DATA, payload: {bio: '', userId: result.uid}})
} catch (err) {
dispatch({type: SIGN_UP_FAIL, payload: {errMessage: err.message}})
}
}
firebaseSignUpUser = async (email, password, displayName) => {
try {
const db = firebase.database()
const result = firebase
.auth()
.createUserAndRetrieveDataWithEmailAndPassword(email, password)
.then(() => {
const user = firebase.auth().currentUser
db.ref('users/' + user.uid).set({
bio: '',
userId: user.uid,
})
const newUser = user
.updateProfile({
displayName: displayName,
photoURL: "https://firebasestorage.googleapis.com/v0/b/newlapar-19607.appspot.com/o/avatar%2Fhappy.png?alt=media&token=51fa7ac1-bab9-4078-9f44-2db77f0f04bd",
})
.then(() => {
const newUser = firebase.auth().currentUser
return newUser
})
.catch(err => console.log(err))
return newUser
})
return result
} catch(err) {
console.log("errmsg: " + err.message)
throw new Error(err.message)
}
}
fetchUserData = async userId => {
console.log("userid: " + userId)
const userData = await firebase.database().ref("users").orderByKey()
.equalTo(userId).once("value")
.then(snapshot => {
return snapshot.val()[userId]
})
console.log("FETCHED USER DATA: " + JSON.stringify(userData))
return userData
}
import React from 'react';
import { Text, View, ScrollView, TouchableHighlight } from 'react-native';
import { SearchBar, CheckBox } from 'react-native-elements';
import Icon from 'react-native-vector-icons/Ionicons';
import VerticalStallsList from '../components/VerticalStallsList';
import { stalls } from '../constants/Test';
import ExploreModal from '../components/ExploreModal'
import { Dimensions } from 'react-native';
import firebase from 'react-native-firebase';
const { width, height } = Dimensions.get('window');
const guidelineBaseWidth = 350;
const guidelineBaseHeight = 680;
const scale = size => width / guidelineBaseWidth * size;
export default class ExploreScreen extends React.Component {
constructor(props) {
super(props);
this.state = {
search: '',
modalVisible: false,
sort: 'rating',
filters: [],
locations: this.props.navigation.state.params === undefined ? [] : [this.props.navigation.state.params.locs],
locs: this.props.navigation.state.params === undefined ? '' : this.props.navigation.state.params.locs,
locationObj: {},
locationNames: null, // array of location names ["Fine Food", "Techno Edge", ...]
stallObj: null,
itemObj: null,
}
}
componentDidMount = () => {
// console.log("state locations: " + this.state.locations)
// console.log("state locs: " + this.state.locs)
// fetch location names
const db = firebase.database()
db.ref("locations").once("value").then(snapshot => {
this.setState({ locationObj: snapshot.val() })
let locationIds = Object.keys(this.state.locationObj)
const locNameArr = locationIds.map((key, idx) => {
return this.state.locationObj[key].name
})
this.setState({ locationNames: locNameArr })
})
// fetch stalls
db.ref("stalls").once("value").then(snapshot => {
this.setState({ stallObj: snapshot.val() })
// console.log("stall obj: " + JSON.stringify(this.state.stallObj))
})
// fetch items
db.ref("items").once("value").then(snapshot => {
this.setState({ itemObj: snapshot.val() })
// console.log("item obj: " + JSON.stringify(this.state.itemObj))
})
}
handleNavigation = () => {
console.log("handleNavigation")
if (this.props.navigation.state.params !== undefined && this.props.navigation.state.params.locs !== this.state.locs) {
this.setState({
locs: this.props.navigation.state.params.locs,
locations: [this.props.navigation.state.params.locs]
})
}
}
handleSearch = text => {
this.setState({ search: text });
}
onOpenModal = () => {
this.setState({ modalVisible: true });
}
onCloseModal = () => {
this.setState({ modalVisible: false });
}
onCheckFilter = criteria => {
const { filters } = this.state;
if (!filters.includes(criteria)) {
this.setState({ filters: [...filters, criteria] });
} else {
this.setState({ filters: filters.filter( c => c !== criteria) });
}
}
onCheckLocation = criteria => {
const { locations } = this.state;
if (!locations.includes(criteria)) {
this.setState({ locations: [...locations, criteria] });
} else {
this.setState({ locations: locations.filter( loc => loc !== criteria) });
}
}
onSortChange = (value, index) => {
this.setState({ sort: value });
}
onClear = () => {
this.setState({ sort: 'rating', filters: [], locations: [] });
}
render() {
this.handleNavigation();
return (
<View style={{ flex: 1, backgroundColor: 'white' }}>
<ExploreModal
modalVisible={this.state.modalVisible}
sort={this.state.sort}
filters={this.state.filters}
locations={this.state.locations}
onCheckFilter={this.onCheckFilter}
onCheckLocation={this.onCheckLocation}
onSortChange={this.onSortChange}
onClear={this.onClear}
onCloseModal={this.onCloseModal}
/>
<View style={{ flexDirection: 'row' }}>
<Icon onPress={this.onOpenModal} name='md-menu' size={scale(30)} color={'white'} style={{ backgroundColor: 'red', paddingLeft: scale(12), paddingTop: scale(10), paddingRight: scale(7) }} />
<SearchBar lightTheme inputStyle={{ backgroundColor: 'white' }} containerStyle={{ backgroundColor: 'red', width: scale(310), borderBottomColor: 'transparent', borderTopColor: 'transparent'}} onChangeText={this.handleSearch} placeholder="Search..." clearIcon />
</View>
{/*<VerticalStallsList sort={this.state.sort} filters={this.state.filters} locations={this.state.locations} search={this.state.search} stalls={stalls} navigation={this.props.navigation} />*/}
{ this.state.itemObj && this.state.stallObj &&
<VerticalStallsList sort={this.state.sort} filters={this.state.filters} locations={this.state.locations} search={this.state.search} stalls={this.state.stallObj} items={this.state.itemObj} navigation={this.props.navigation} />
}
</View>
);
}
}
import React from 'react';
import { Text, ScrollView, View, TouchableWithoutFeedback } from 'react-native';
import { SearchBar } from 'react-native-elements';
import firebase from 'react-native-firebase';
import HorizontalItemsSwiper from '../components/HorizontalItemsSwiper';
import HorizontalLocsList from '../components/HorizontalLocsList';
import { locs, items } from '../constants/Test';
export default class HomeScreen extends React.Component {
constructor() {
super()
this.state = {
currentUser: null,
recommendedItems: {},
top5: {},
locations: {},
}
}
componentDidMount = () => {
console.log("home screen did mount")
firebase.auth().onAuthStateChanged(user => {
if (user) {
this.setState({ currentUser: user })
console.log("currentUser: " + JSON.stringify(this.state.currentUser))
// console.log("current user uid: " + this.state.currentUser.uid)
} else {
// this.setState({ currentUser: null })
console.log("NO CURRENT USER?")
}
})
const db = firebase.database()
// fetch recommended items
db.ref("items").orderByChild("recommended").equalTo(true).once("value").then(snapshot => {
this.setState({ recommendedItems: snapshot.val() })
})
// fetch top 5 items
db.ref("items").orderByChild("ratings").limitToFirst(5).once("value").then(snapshot => {
this.setState({ top5: snapshot.val() })
})
// fetch locations
db.ref("locations").orderByChild("name").once("value").then(snapshot => {
this.setState({ locations: snapshot.val() })
})
}
render() {
return (
<View style={{ flex: 1, backgroundColor: 'white' }}>
<TouchableWithoutFeedback onPress={() => this.props.navigation.navigate('Explore')}>
<View>
<SearchBar inputStyle={{ backgroundColor: 'white' }} containerStyle={{ backgroundColor: 'red', borderBottomColor: 'transparent', borderTopColor: 'transparent' }} placeholder="Search..." clearIcon />
</View>
</TouchableWithoutFeedback>
<Text style={{ marginTop: 10, marginLeft: 10, marginBottom: 5, fontSize: 18, color: 'black' }}>Recommendations</Text>
{this.state.currentUser &&
<HorizontalItemsSwiper items={this.state.recommendedItems} userId={this.state.currentUser.uid} navigation={this.props.navigation} />
}
<Text style={{ marginTop: 10, marginLeft: 10, marginBottom: 5, fontSize: 18, color: 'black' }}>Top 5</Text>
{this.state.currentUser &&
<HorizontalItemsSwiper items={this.state.top5} userId={this.state.currentUser.uid} navigation={this.props.navigation} />
}
<Text style={{ marginTop: 10, marginLeft: 10, fontSize: 18, color: 'black' }}>Locations</Text>
{this.state.currentUser &&
<HorizontalLocsList locs={this.state.locations} userId={this.state.currentUser.uid} navigation={this.props.navigation} />
}
<Text>{'\n'}</Text>
</View>
);
}
}
import React from 'react'
import { StyleSheet, Text, TextInput, View, Image, Dimensions } from 'react-native'
import { Button } from 'react-native-elements'
import firebase from 'react-native-firebase'
import {logInUser} from '../redux/actions'
import {connect} from 'react-redux'
import store from '../redux/store'
const { width, height } = Dimensions.get('window');
const guidelineBaseWidth = 350;
const guidelineBaseHeight = 680;
const scale = size => width / guidelineBaseWidth * size;
const verticalScale = size => height / guidelineBaseHeight * size;
class LoginScreen extends React.Component {
state = {
email: '',
password: '',
}
componentDidUpdate(prevProps) {
// Typical usage (don't forget to compare props):
if (this.props.currentUser !== prevProps.currentUser
&& this.props.userData !== prevProps.userData) {
console.log("comp did update, userData: " + JSON.stringify(this.props.userData))
this.props.navigation.navigate('Home')
}
}
handleLogin = () => {
this.props.logInUser(this.state.email, this.state.password)
}
render() {
return (
<View style={styles.container}>
{this.props.errMessage &&
<Text style={{ color: 'red' }}>
{this.props.errMessage}
</Text>}
<Image source={require('../assets/images/logo.png')} style={{ width: scale(100), height: verticalScale(150) }}/>
<TextInput
style={styles.textInput}
autoCapitalize="none"
placeholder="Email"
onChangeText={ email => this.setState({ email })}
value={this.state.email}
/>
<TextInput
secureTextEntry
style={styles.textInput}
autoCapitalize="none"
placeholder="Password"
onChangeText={ password => this.setState({ password })}
value={this.state.password}
/>
<Button
title="Login"
textStyle={{ fontWeight: 'bold' }}
buttonStyle={{ marginTop: 20, marginBottom: 10, backgroundColor: 'red', width: scale(120), borderRadius: 40 }}
onPress={this.handleLogin} />
<Text>- OR -</Text>
<Button
title="Sign Up"
textStyle={{ color: 'red' }}
buttonStyle={{ marginTop: 10, backgroundColor: 'white', width: scale(120), borderRadius: 40, borderColor: 'red', borderWidth: 1 }}
onPress={() => this.props.navigation.navigate('SignUp')}
/>
</View>
)
}
}
const mapStateToProps = state => ({
errMessage: state.user.errMessage,
currentUser: state.user.currentUser,
userData: state.user.userData
})
export default connect(mapStateToProps, {logInUser})(LoginScreen)
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'white'
},
textInput: {
height: 40,
width: '80%',
borderBottomColor: 'gray',
borderBottomWidth: 1,
marginTop: 8,
marginBottom: 10
}
})
import React from 'react';
import { Text, View, Button, StyleSheet, Image, ActivityIndicator, ScrollView, TextInput } from 'react-native';
import firebase from 'react-native-firebase';
import { Avatar, Card } from 'react-native-elements'
import Icon from 'react-native-vector-icons/Octicons'
import EditProfileModal from '../components/EditProfileModal'
import VerticalReviewsList from '../components/VerticalReviewsList'
import { Dimensions } from 'react-native';
const { width, height } = Dimensions.get('window');
const guidelineBaseWidth = 350;
const guidelineBaseHeight = 680;
const scale = size => width / guidelineBaseWidth * size;
export default class newProfileScreen extends React.Component {
constructor() {
super()
this.state = {
currentUser: null,
userData: {
displayName: '',
email: '',
username: '',
uid: '',
bio: '',
preferences: '',
photoURL: null,
userID: '',
},
modalVisible: false,
modalDisplayName: '',
modalUsername: '',
modalEmail: '',
modalBio: '',
modalPreferences: '',
modalPhotoURL: null,
isLoading: true,
reviewIds: [],
}
}
componentDidMount = () => {
console.log("in profilescreen didmount")
const currentUser = firebase.auth().currentUser;
const db = firebase.database()
if (currentUser != null) {
this.setCurrentUser(currentUser)
db.ref("users").orderByKey().equalTo(currentUser.uid).once("value").then(snapshot => {
return snapshot.val()[currentUser.uid]
}).then(userData => {
this.setUserData(userData)
}).then(() => this.setState({ isLoading: false }))
// fetch reviews
db.ref("users/" + currentUser.uid).orderByKey().equalTo("reviews").once("value").then(snapshot => {
if (snapshot.val() !== null) {
console.log("reviews: " + JSON.stringify(snapshot.val().reviews))
this.setState({ reviewIds: snapshot.val().reviews })
}
})
// add listener for added review
db.ref("users/" + currentUser.uid + "/reviews/").on("child_added", snapshot => {
console.log("\nGOT ADDED CHILD IN PROFILE SCREEN\n")
// fetch user reviewIds again, set as state to trigger re render
db.ref("users/" + currentUser.uid).orderByKey().equalTo("reviews").once("value").then(snapshot => {
console.log("re fetched reviews: " + JSON.stringify(snapshot.val().reviews))
this.setState({ reviewIds: snapshot.val().reviews })
})
})
}
}
setCurrentUser = currentUser => {
this.setState({ currentUser })
}
setUserData = userData => {
this.setState({
userData: {
displayName: this.state.currentUser && this.state.currentUser.displayName,
email: this.state.currentUser && this.state.currentUser.email,
photoURL: this.state.currentUser && this.state.currentUser.photoURL,
...userData
}
})
}
handleEditProfile = () => {
this.setState({
modalVisible: true,
modalDisplayName: this.state.userData && this.state.userData.displayName,
modalEmail: this.state.userData && this.state.userData.email,
modalUsername: this.state.userData && this.state.userData.username,
modalBio: this.state.userData && this.state.userData.bio,
modalPreferences: this.state.userData && this.state.userData.preferences,
modalPhotoURL: this.state.userData && this.state.userData.photoURL,
});
}
handleSaveChanges = () => {
const user = this.state.currentUser
user.updateProfile({
displayName: this.state.modalDisplayName,
photoURL: this.state.modalPhotoURL,
})
.then(() => {
user.updateEmail(this.state.modalEmail)
const db = firebase.database()
db.ref("users/" + user.uid).update({
username: this.state.modalUsername,
bio: this.state.modalBio,
preferences: this.state.modalPreferences,
})
})
.then(() => {
this.setState({
userData: {
displayName: this.state.modalDisplayName,
email: this.state.modalEmail,
username: this.state.modalUsername,
bio: this.state.modalBio,
preferences: this.state.modalPreferences,
photoURL: this.state.modalPhotoURL,
},
modalVisible: false
})
})
}
handleSignOut = () => {
firebase.auth().signOut()
this.props.navigation.navigate('Login')
}
changePassword = (email, oldPassword, newPassword) => {
const user = firebase.auth().currentUser;
const credential = firebase.auth.EmailAuthProvider.credential(email, oldPassword)
user.reauthenticateAndRetrieveDataWithCredential(credential).then(() => {
firebase.auth().currentUser.updatePassword(newPassword).then(() => {
"successfully changed pw"
}).catch(e => console.log(e))
}).catch(e => console.log(e))
}
render() {
console.log("in profile " + JSON.stringify(this.state.reviewIds))
let screen
if (this.state.isLoading || this.state.reviewIds.length === 0) {
// if (this.state.isLoading) {
screen = <ActivityIndicator size="large" color="#0000ff" />
} else {
screen =
<ScrollView style={{ backgroundColor: 'white' }}>
<View style={{ flexDirection: 'row' }}>
<Text style={{ width: scale(310), backgroundColor: 'red', color: 'white', paddingLeft: scale(20), paddingTop: scale(13), paddingBottom: scale(13), fontSize: 22, fontWeight: 'bold' }}>Profile</Text>
<Icon onPress={this.handleSignOut} name='sign-out' size={scale(25)} color={'white'} style={{ backgroundColor: 'red', paddingLeft: scale(10), paddingTop: scale(15), paddingRight: scale(5) }} />
</View>
<View style={styles.container}>
{ this.state.userData &&
<Avatar
large
rounded
source={{uri: this.state.userData.photoURL}}
onPress={() => alert("View enlarged picture")}
activeOpacity={0.7}
/>
}
<Text style={{ fontSize: 20, color: 'black' }}>{this.state.userData && this.state.userData.displayName}</Text>
<Text style={{ color: 'gray', marginBottom: 10, marginLeft: 20, marginRight: 20 }}>{this.state.userData && this.state.userData.bio}</Text>
<Button title='Edit Profile' color={'red'} onPress={this.handleEditProfile} />
</View>
<VerticalReviewsList reviews={this.state.reviewIds} />
<Text>{'\n'}</Text>
<EditProfileModal
modalVisible={this.state.modalVisible}
currentUser={this.state.currentUser}
displayName={this.state.modalDisplayName}
userID={this.state.userData.userID}
username={this.state.modalUsername}
email={this.state.modalEmail}
bio={this.state.modalBio}
preferences={this.state.modalPreferences}
photoURL={this.state.modalPhotoURL}
onChangeDisplayName={ modalDisplayName => this.setState({ modalDisplayName }) }
onChangeEmail={ modalEmail => this.setState({ modalEmail }) }
onChangeUsername={ modalUsername => this.setState({ modalUsername }) }
onChangeBio={ modalBio => this.setState({ modalBio }) }
onChangePreferences={ modalPreferences => this.setState({ modalPreferences }) }
onChangePhotoURL={ modalPhotoURL => this.setState({ modalPhotoURL }) }
handleSaveChanges={this.handleSaveChanges}
handleClose={ () => this.setState({ modalVisible: false })}
/>
</ScrollView>
}
return (
<View style={{ flex: 1, alignItems: 'center' }}>{screen}</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'white',
paddingTop: 10,
paddingBottom: 10,
borderBottomColor: '#d9dce0',
borderBottomWidth: 1
},
textInput: {
height: 40,
width: '90%',
borderColor: 'gray',
borderWidth: 1,
marginTop: 8
},
image: {
height: 150,
width: 350
}
})
import React from 'react'
import { View, Text, StyleSheet, TextInput, Image, Picker } from 'react-native'
import { Button } from 'react-native-elements'
import { Dimensions } from 'react-native';
const { width, height } = Dimensions.get('window');
const guidelineBaseWidth = 350;
const guidelineBaseHeight = 680;
const scale = size => width / guidelineBaseWidth * size;
const verticalScale = size => height / guidelineBaseHeight * size;
import firebase from 'react-native-firebase'
import {connect} from 'react-redux'
import {indicateSignUpStall, setUserData} from '../redux/actions'
class StallOwnerSignUpScreen extends React.Component {
constructor() {
super()
this.state = {
email: '',
password: '',
stallName: '',
stallLocation: 'Techno Edge',
locationList: [],
locNameToLocIdHashtable: {},
errorMessage: null
}
}
componentDidMount = () => {
// fetch list of locations for location dropdown
firebase.database().ref("locations/").once("value").then(snapshot => {
console.log("locations data: " + JSON.stringify(snapshot.val()))
const locationsObj = snapshot.val()
const locNamesArr = Object.keys(locationsObj).map((locId, idx) => {
return locationsObj[locId].name
})
this.setState({ locationList: locNamesArr })
let hash = {}
Object.keys(locationsObj).forEach((id, idx) => {
hash[locationsObj[id].name] = id
})
this.setState({ locNameToLocIdHashtable: hash })
})
}
handleSignUp = () => {
// this.props.signUpStallOwner(this.state.email, this.state.password, this.state.stallName, this.state.stallLocation)
this.props.indicateSignUpStall()
firebase
.auth()
.createUserAndRetrieveDataWithEmailAndPassword(this.state.email, this.state.password)
.then(() => {
const user = firebase.auth().currentUser
user
.updateProfile({
displayName: this.state.stallName,
photoURL: "https://images.unsplash.com/photo-1483137140003-ae073b395549?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=1e392896fc645f9fc3797c9bb7dab4d3&auto=format&fit=crop&w=1350&q=80",
})
.then(() => {
console.log("update stall success")
// create a new stall
const newStallRef = firebase.database().ref("stalls").push();
const stallId = newStallRef.key
console.log("newStallRef: " + newStallRef)
console.log("stallId: " + stallId)
newStallRef.set({
name: this.state.stallName,
location: this.state.stallLocation,
stallId: stallId,
owner: user.uid
})
return stallId
})
.then(stallId => {
console.log("saving stall id in user")
const userData = {isStall: true, stallId: stallId}
// save the stall id in user
firebase.database().ref('users/' + user.uid).set(userData)
// save in location too
const locId = this.state.locNameToLocIdHashtable[this.state.stallLocation]
let newStall = {}
newStall[stallId] = true
firebase.database().ref('locations/' + locId + '/stalls/').update(newStall)
// manually dispatch action to set user data without fetching
this.props.setUserData(userData)
})
.catch(err => console.log(err))
})
}
render() {
const locationsPicker = this.state.locationList.map((loc, index) => {
return <Picker.Item key={index} label={loc} value={loc} />
})
return (
<View style={styles.container}>
<Image source={require('../assets/images/logo.png')} style={{ width: scale(100), height: verticalScale(150) }}/>
{this.state.errorMessage &&
<Text style={{ color: 'red' }}>
{this.state.errorMessage}
</Text>}
{/* Email */}
<TextInput
placeholder="Email"
autoCapitalize="none"
style={styles.textInput}
onChangeText={email => this.setState({ email })}
value={this.state.email}
/>
{/* Password */}
<TextInput
secureTextEntry
placeholder="Password"
autoCapitalize="none"
style={styles.textInput}
onChangeText={password => this.setState({ password })}
value={this.state.password}
/>
<TextInput
placeholder="Stall Name"
autoCapitalize="none"
style={styles.textInput}
onChangeText={stallName => this.setState({ stallName })}
value={this.state.stallName}
/>
{/*<TextInput
placeholder="Stall Location"
autoCapitalize="none"
style={styles.textInput}
onChangeText={stallLocation => this.setState({ stallLocation })}
value={this.state.stallLocation}
/>*/}
<Picker
selectedValue={this.state.stallLocation}
style={{ height: 40, width: '80%' }}
onValueChange={(itemValue, itemIndex) => this.setState({ stallLocation: itemValue })}
>
{locationsPicker}
</Picker>
<Button
title="Create Account"
textStyle={{ fontWeight: 'bold' }}
buttonStyle={{ marginTop: 20, marginBottom: 10, backgroundColor: 'red', width: scale(120), borderRadius: 40 }}
onPress={this.handleSignUp} />
<Text>- OR -</Text>
<Button
title="Login"
textStyle={{ color: 'red' }}
buttonStyle={{ marginTop: 10, backgroundColor: 'white', width: scale(120), borderRadius: 40, borderColor: 'red', borderWidth: 1 }}
onPress={() => this.props.navigation.navigate('Login')}
/>
</View>
)
}
}
mapDispatchToProps = {
indicateSignUpStall: indicateSignUpStall,
setUserData: setUserData
}
export default connect(null, mapDispatchToProps)(StallOwnerSignUpScreen)
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'white'
},
textInput: {
height: 40,
width: '80%',
borderBottomColor: 'gray',
borderBottomWidth: 1,
marginTop: 8,
marginBottom: 10
}
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment