If you don't want to read this and just want to view the code then it
can be found here. This walk-thru assumes you know the basics of
firebase.
------------------------------------------------------------------------
Setup
-----
1. If you haven't already you want to follow the instructions
[here](https://www.npmjs.com/get-npm) to download npm.
2. Go
[here](https://facebook.github.io/react-native/docs/getting-started.html)
to get the react-native cli for your given platform
3. In your project space of choice (I typically use my desktop) run
`react-native init <Project Name>`
4. Once your app is created cd into that new project folder and then
run `react-native run-ios ` or `react-native run-android`
5. Make sure you see the default react native screen with instructions
on how to refresh the app
------------------------------------------------------------------------
Let's get coding {#letsgetcoding}
----------------
Open up your new project in your Text Editor of choice (I use VS Code)
and take a look at the file structure. Setup your new firebase project
and copy the info for a new web app (or copy my stuff). Open your
`App.js` to look like this:
import * as firebase from 'firebase';
const config = {
apiKey: "AIzaSyCwE3hbbjog48VhhSYdCyxKF0lJA3vA3Xg",
authDomain: "inventoryapp-f69f2.firebaseapp.com",
databaseURL: "https://inventoryapp-f69f2.firebaseio.com",
projectId: "inventoryapp-f69f2",
storageBucket: "",
};
firebase.initializeApp(config);
var database = firebase.database();
export default class App extends Component {
...
}
Finally run `npm install firebase` so we can make sure that our firebase
import doesn't throw errors. Now that we have added Firebase to our app
lets create a new folder in your project called `Components` and within
that folder create 3 files `Header.js`, `ListItem.js`, and `Button.js`.
*Header.js* give us the nice little title bar at the top of our screen.
*ListItem.js* helps us setup what each row of our list view will look
like. *Button.js* will help us create a custom button for our app.
Header.js:
import React, {Component} from 'react';
import { View, Text } from 'react-native';
class Header extends Component {
render() {
return (
<View>
<View style={styles.header}/>
<View style={styles.navbar}>
<Text style={styles.navbarTitle}>{this.props.title}
</Text>
</View>
</View>
);
}
};
const styles = {
navbar: {
alignItems: 'center',
backgroundColor: '#fff',
borderBottomColor: '#eee',
borderColor: 'transparent',
borderWidth: 1,
justifyContent: 'center',
height: 44,
flexDirection: 'row'
},
navbarTitle: {
color: '#444',
fontSize: 16,
fontWeight: "500"
},
header: {
backgroundColor: '#fff',
height: 22,
}
};
export default Header;
ListItem.js:
import React, {Component} from 'react';
import { View, TouchableHighlight, Text, Image, Button } from 'react-native';
class ListItem extends Component {
render() {
return (
<TouchableHighlight onPress={this.props.onPress} onLongPress={this.props.onLongPress}>
<View style={styles.li}>
<Text style={styles.liTitle}>{this.props.item.title}</Text>
</View>
</TouchableHighlight>
);
}
};
const styles = {
li: {
backgroundColor: '#fff',
borderBottomColor: '#eee',
borderColor: 'transparent',
borderWidth: 1,
paddingLeft: 16,
paddingTop: 14,
paddingBottom: 16
},
liTitle: {
color: '#333',
fontSize: 16
},
};
export default ListItem;
Button.js:
import React, {Component} from 'react';
import { View, Text, TouchableHighlight } from 'react-native';
class Button extends Component {
render() {
return (
<View style={styles.action}>
<TouchableHighlight onPress={this.props.onPress}>
<Text style={styles.actionText}>{this.props.title}</Text>
</TouchableHighlight>
</View>
);
};
};
const styles = {
actionText: {
color: '#fff',
fontSize: 16,
textAlign: 'center',
},
action: {
backgroundColor: '#24CE84',
borderColor: 'transparent',
borderWidth: 1,
paddingLeft: 16,
paddingTop: 14,
paddingBottom: 16,
},
};
export default Button;
Now we can work on putting everything together. So let's return to
`App.js` and do some code and checks.
------------------------------------------------------------------------
Let's add in our components and everything but we aren't going to have
any items in our list nor. We just want to make sure everything has the
look we want.
import React, {Component} from 'react';
import {View, ListView, Alert, AlertIOS} from 'react-native';
import Header from './components/Header'
import ListItem from './components/ListItem';
import Button from './components/Button';
import * as firebase from 'firebase';
const config = {
apiKey: "AIzaSyCwE3hbbjog48VhhSYdCyxKF0lJA3vA3Xg",
authDomain: "inventoryapp-f69f2.firebaseapp.com",
databaseURL: "https://inventoryapp-f69f2.firebaseio.com",
projectId: "inventoryapp-f69f2",
storageBucket: "",
};
firebase.initializeApp(config);
var database = firebase.database();
export default class App extends Component {
/*Setup and state*/
constructor(props) {
super(props);
this.state = {
dataSource: new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 !== row2
})
};
this.itemsRef = database.ref('inventorySimple');
}
componentDidMount(){
this.listenForItem(this.itemsRef);
}
componentDidUnMount(){
this.state.itemsRef.off('value');
}
render() {
return (
<View style={styles.container}>
<Header title="Inventory Simple"/>
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderItem.bind(this)}
enableEmptySections={true}
style={styles.listview}/>
<Button title="Add Item" onPress={this.addItem.bind(this)} />
</View>
)
}
renderItem(item) {
const onPress = () => {};
const onLongPress = () => {};
return(
<ListItem item={item} onPress={onPress} onLongPress={onLongPress}/>
);
}
listenForItem(itemsRef){}
addItem() {}
}
const styles = {
container: {
backgroundColor: '#f2f2f2',
flex: 1,
},
listview: {
flex:1
}
};
P.S.: run `npm install` if you get an error.
Now that we know this looks pretty decent let's update our renderItems
listenForItems, and addItems method so that we can add random stuff.
...
renderItem(item) {
const onPress = () => {
Alert.alert(
'Delete Item',
'delete ' + item.title + ' ?',
[
{text: 'Cancel', onPress: () => console.log('cancel Pressed'), style: 'cancel'},
{text: 'OK', onPress: () => this.itemsRef.child(item._key).remove()},
],
{cancelable: false}
)
};
const onLongPress = () => {
AlertIOS.prompt(
'Edit Item',
'current item is ' + item.title,
[
{text: 'Cancel', onPress: () => console.log('cancel Pressed'), style: 'cancel'},
{text: 'OK', onPress: (text) => this.itemsRef.child(item._key).update({title: text})},
],
)
};
return(
<ListItem item={item} onPress={onPress} onLongPress={onLongPress}/>
);
}
listenForItem(itemsRef){
itemsRef.on('value', (snap) => {
//get array of children
var items = [];
snap.forEach((child) => {
items.push({
title: child.val().title,
_key: child.key
});
});
this.setState({
dataSource: this.state.dataSource.cloneWithRows(items)
});
});
}
addItem() {
AlertIOS.prompt(
'Add Item',
null,
[
{text: 'Cancel', onPress: () => console.log('cancel Pressed'), style: 'cancel'},
{text: 'OK', onPress: (text) => this.itemsRef.push({ title: text})},
],
)
}
...
And that's it! Congrats on getting your app to work. You can use this as
a template and then make some even cooler stuff.
------------------------------------------------------------------------
P.S. If you want a more "robust" app using navigator and everything
check out this [repo](https://github.com/BackpackMedia/Inventory-App).
First published on
[Medium](https://medium.com/@keheira/firebase-react-native-building-an-inventory-app-baea00b3d629)