React Native has been around quite some time, so now it’s time to take a closer look at all the cool things we can build with it. This time we will connect to the cloud database service Firebase and see why this provider is very popular among mobile developers.
In this tutorial we will build a simple Todo app, where all of our todos are added to our database on Firebase. For now we won’t use the authentication features of Firebase, but if you want to see how this is done just leave me a comment!
At the end of this tutorial you will know how to use Firebase, how to sync your cloud data to your React Native app in real time, how to update upon changes and also how to craft a simple listview component with React Native, which is comparable to the iOS Tableview.
If you haven’t created an account at Firebase, now is the time. It’s free and straight forward right now, even your first database should be created automatically. We will need that URL later!
Setup a clean React Native app
We start with a new app, so at this point you should have React Native installed. If you need help setting up everything, check out my introduction to React Native.
If you are ready, run:
react-native init devdacticFirebase cd devdacticFirebase npm install firebase --save
We now have the basic starter app plus the firebase package installed with NPM. Next, open your index.ios.js and delete everything inside. Yes, just do it.
We will go through everything step-by-step, and we will also use the ES6 syntax which is not the basic setup. If your file is clean, start with adding the dependencies we need to craft our app view (by using destructuring) and also keep a reference to the Firebase plugin:
var React = require('react-native'); var { Component, AppRegistry, StyleSheet, Text, View, TouchableHighlight, TextInput, ListView } = React; var Firebase = require('firebase');
To get our app running as fast as possible, we add our class and implement a simple dummy constructor. Also below we got already the styles variable which will hold all the app style, and finally our app is registered so we can run something.
At this step you need to include the Firebase URL of your database. The package will open a connection, and we can use all the endpoints of the web api for updating our database. So go ahead and add this:
class devdacticFirebase extends Component { // Your App Code constructor(props) { super(props); var myFirebaseRef = new Firebase('https://.firebaseio.com'); myFirebaseRef.set({ title: "Hello World!", author: "Simon", location: { city: "Muenster", state: "Germany", zip: 48155 } }); } } var styles = StyleSheet.create({ // Your App Style }); AppRegistry.registerComponent('devdacticFirebase', () => devdacticFirebase);
If you have replaced your Firebase URL, you can start the Xcode Project and run the app on the simulator/device. Also keep an eye on your hopefully clean Firebase database in the browser.
Once your app starts, it will crash because we have no render() function, but if you take a look at your database you should see something like this:
So if this is working, you have everything you need ready to build great apps with a cloud backend (and also to continue this tutorial)!
Set and remove Data from Firebase
Right now we have just set static data from our constructor (which is already quite awesome, isn’t it??), but we want to init our app with data from the database, and also add and remove todos using our app.
First of all, replace the previously created constructor with this new one:
constructor(props) { super(props); var myFirebaseRef = new Firebase('https://.firebaseio.com'); this.itemsRef = myFirebaseRef.child('items'); this.state = { newTodo: '', todoSource: new ListView.DataSource({rowHasChanged: (row1, row2) => row1 !== row2}) }; this.items = []; }
Again we create a reference to our Firebase database (make sure to add your id) but this time we also create a itemsRef which will point to items as a child of the root node at firebase. By doing this we can keep all todos below this child node and keep a clean structure for the backend.
Additional we set the basic state of our app with a variable newTodo
which will be connected to an input field and also the todoSource
which is the datasource for the ListView we will create later.
The componentDidMount()
method is called once when our app is created, so this is a good point to register ourself on database events. For our Todo app, we want to listen for the Firebase child_added and child_removed events.
This means, every time an entry is added or removed to our Firebase storage, our app will receive this event. Quite awesome, right? So add this method below the constructor:
componentDidMount() { // When a todo is added this.itemsRef.on('child_added', (dataSnapshot) => { this.items.push({id: dataSnapshot.key(), text: dataSnapshot.val()}); this.setState({ todoSource: this.state.todoSource.cloneWithRows(this.items) }); }); // When a todo is removed this.itemsRef.on('child_removed', (dataSnapshot) => { this.items = this.items.filter((x) => x.id !== dataSnapshot.key()); this.setState({ todoSource: this.state.todoSource.cloneWithRows(this.items) }); }); }
When an item is added, we just push the new value to our items array and update the datasource for our list.
If an item get’s removed, we use the filter function to remove the one item from our array matching the removed key. By using dataSnapshot.key()
we get the from Firebase automatically created unique id of the entry.
Adding a todo is even more easier, we only have to call push()
on our connection to Firebase and an Object like {todo: ‘the todo text’} will be pushed to the cloud. So go ahead and add the next method to our class:
addTodo() { if (this.state.newTodo !== '') { this.itemsRef.push({ todo: this.state.newTodo }); this.setState({ newTodo : '' }); } }
The last functionality we need is to remove a todo, so also add this method:
removeTodo(rowData) { this.itemsRef.child(rowData.id).remove(); }
As you can see, we only need to get the correct child of our Firebase by using the id and calling remove()
. The rest will be handled by the events our app receives, which means this is the complete logic for adding and removing the data now!
Do you have any problems to this point?
Craft a simple Todo App View
The last missing part of our app is the view, so let’s create one!
Our app will consist of a stylish tobbar with our app title, an input container for new todos and a button to submit the todo to our Firebase, and a listview displaying all of our todos.
There is nothing special about this code, the most interesting part will be the listview, so first of all add this method to our class:
render() { return ( <View style={styles.appContainer}> <View style={styles.titleView}> <Text style={styles.titleText}> My Todos </Text> </View> <View style={styles.inputcontainer}> <TextInput style={styles.input} onChangeText={(text) => this.setState({newTodo: text})} value={this.state.newTodo}/> <TouchableHighlight style={styles.button} onPress={() => this.addTodo()} underlayColor='#dddddd'> <Text style={styles.btnText}>Add!</Text> </TouchableHighlight> </View> <ListView dataSource={this.state.todoSource} renderRow={this.renderRow.bind(this)} /> </View> ); }
The datasource is our todo array, and renderRow will call another method for each row. Go ahead and also add the method for creating every row:
renderRow(rowData) { return ( <TouchableHighlight underlayColor='#dddddd' onPress={() => this.removeTodo(rowData)}> <View> <View style={styles.row}> <Text style={styles.todoText}>{rowData.text}</Text> </View> <View style={styles.separator} /> </View> </TouchableHighlight> ); }
By clicking on a row we delete a todo, and also the row holds the text of a todo. Quite easy, right?
So now all of our rows and the rest of the view will be rendered, but it will look like shit. Yeah, obviously the last part missing is some styling. I don’t want to go through this in detail, so for more information also take a look at my React Native Tab Bar tutorial.
Finally, add this styling below the class and also replace the dummy styling which has no style at all right now:
var styles = StyleSheet.create({ appContainer:{ flex: 1 }, titleView:{ backgroundColor: '#48afdb', paddingTop: 30, paddingBottom: 10, flexDirection: 'row' }, titleText:{ color: '#fff', textAlign: 'center', fontWeight: 'bold', flex: 1, fontSize: 20, }, inputcontainer: { marginTop: 5, padding: 10, flexDirection: 'row' }, button: { height: 36, flex: 2, flexDirection: 'row', backgroundColor: '#48afdb', justifyContent: 'center', color: '#FFFFFF', borderRadius: 4, }, btnText: { fontSize: 18, color: '#fff', marginTop: 6, }, input: { height: 36, padding: 4, marginRight: 5, flex: 4, fontSize: 18, borderWidth: 1, borderColor: '#48afdb', borderRadius: 4, color: '#48BBEC' }, row: { flexDirection: 'row', padding: 12, height: 44 }, separator: { height: 1, backgroundColor: '#CCCCCC', }, todoText: { flex: 1, } });
If you run or refresh your app now, you should have a completely functional Todo app. You can add todos, remove todos and scroll through them. Also make sure to watch the updates on your Firebase backend! The resulting app should look like this:
Conclusion
In this tutorial you learned how to create a simple React Native todo app using the Firebase cloud backend for syncing data. With only a few steps you are able to create an awesome flexible and easy to integrate backend!
If you encounter any problems or want more React Native stuff, I would be happy if you leave a comment below and share my post!
Watch a video of this tutorial below!
So long,
Simon
The post Building a Simple ToDo App With React Native and Firebase appeared first on Devdactic.