Today, I’m going to teach you how to sell your soul to the devil. Let’s build an app to accomplish this goal. In this way, you’ll learn something while selling your soul. The journey is divided into 5 easy steps, and the tech we are going to use is React Native and Firebase. Let’s dive right in!
The first step is to set up the basics. To make this easy we’ll use the create-react which sets everything up for us.
$ npm install -g react-native
$ create-react init signHere
$ cd signHere
$ react-native run-ios
The result:
We got our app! But, it needs a lot of work to be done before it’ll be useful. I always use GitHub in order to control my source code. Follow the steps below if you also want to keep track of your code. If this is the first time you hear of source control or GitHub, check out this resource.
$ git init
$ git add .
$ git commit -m "Step 1: Create React Native app"
$ git remote add origin https://github.com/antonderegt/sign-here.git
$ git push -u origin master
In order to sell our souls, we need to provide our first name, last name, and signature. Let’s make a form so that we can enter these credentials. In this step, we will make changes in the App.js file located in the root of the project. I never like tutorials that only give the parts of the code that changed. I always mess up where to paste the code. I’m going to copy the code anyway so why not just provide the whole code!? So, here you go.
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
TextInput,
Button
} from 'react-native';
export default class App extends Component{
constructor(props) {
super(props);
this.state = {
firstName: 'Thomas',
lastName: 'Ranger',
signature: ''
};
}
render() {
return (
<View style={styles.container}>
<Text style={styles.title}>
Sell your SOUL to the devil
</Text>
<Text style={styles.text}>
All you have to do is sign here
</Text><Text></Text><Text></Text>
<View style={styles.form}>
<Text style={styles.formText}>
First Name
</Text>
<TextInput
style={styles.textInput}
onChangeText={(firstName) => this.setState({firstName})}
value={this.state.firstName}
/>
<Text style={styles.formText}>
Last Name
</Text>
<TextInput
style={styles.textInput}
onChangeText={(lastName) => this.setState({lastName})}
value={this.state.lastName}
/>
<Text style={styles.formText}>
Signature
</Text>
<TextInput
style={styles.signatureInput}
onChangeText={(signature) => this.setState({signature})}
value={this.state.signature}
multiline = {true}
/>
<Button
onPress={()=>console.log('Pressed')}
title="SELL IT"
color="#841584"
/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
title: {
fontSize: 30,
textAlign: 'center',
margin: 10,
},
text: {
textAlign: 'left',
color: '#333333',
marginBottom: 5,
},
form: {
width: '65%',
backgroundColor: '#F5FCFF',
},
formText: {
fontWeight: 'bold'
},
textInput: {
textAlign: 'left',
color: '#333333',
backgroundColor: '#FFF',
marginBottom: 5,
},
signatureInput: {
textAlign: 'left',
color: '#333333',
backgroundColor: '#FFF',
marginBottom: 5,
height: 60
},
});
As you can see in the code above, a constructor was added, this constructor keeps track of the state. The credentials of Thomas are prepopulated for demo purposes. The biggest change comes from inside the render function. The title changed, a basic form was added and finally a button to submit the form. To make it all look a little better styles were added and improved. Copy the code and reload your simulator. In the picture below you can see the idea for the layout of the app. In the next steps, we’ll add the signature box and a way to upload our data.
Step 2 is done, we can upload our code.
$ git add .
$ git commit -m "Step 2: Basic layout"
$ git push origin master
Selling your soul is a memorable moment, we should put a little more effort in the design. We will use a combination of the modules React Native Form and Native Base for that. Here’s how you can install them.
$ npm install react-native-form --save
$ npm install native-base --save
Copy this code to implement our new design.
import React, { Component } from 'react';
import {
StyleSheet,
View,
} from 'react-native';
import {
Text,
Item,
Label,
Input,
Button,
} from 'native-base';
import Form from 'react-native-form'
export default class App extends Component{
constructor(props) {
super(props);
this.state = {
};
}
render() {
return (
<View style={styles.container}>
<Text style={styles.title}>
Sell your SOUL to the devil
</Text>
<Text style={styles.text}>
All you have to do is sign here
</Text><Text></Text><Text></Text>
<Form ref="credentials" style={styles.form} >
<Item floatingLabel style={{marginTop:10}}>
<Label style={{marginLeft: 15}}>First name</Label>
<Input style={{marginLeft: 25}} name="firstName" type="TextInput" />
</Item>
<Item floatingLabel style={{marginTop:10}}>
<Label style={{marginLeft: 15}}>Last name</Label>
<Input style={{marginLeft: 25}} name="lastName" type="TextInput" />
</Item>
<Item floatingLabel style={{marginTop:10}}>
<Label style={{marginLeft: 15}}>Signature</Label>
<Input style={{marginLeft: 25}} name="signature" type="TextInput" />
</Item>
<Button Block primary onPress={() => {console.log('Button clicked')}} style={styles.button}><Text>Sell it</Text></Button>
</Form>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
title: {
fontSize: 30,
textAlign: 'center',
margin: 10,
},
text: {
textAlign: 'left',
color: '#333333',
marginBottom: 5,
},
form: {
width: '80%'
},
button: {
margin: 10
}
});
We added a few nice floating labels and we now use a reference to the form to access the form values.
Another step is done!
$ git add .
$ git commit -m "Step 3: Making the form pretty"
$ git push origin master
We added a few nice floating labels and we now use a reference to the form to access the form values.
Another step is done!
$ git add .
$ git commit -m "Step 3: Making the form pretty"
$ git push origin master
In this step, we will see how to save our data in the cloud with Firebase. If you don’t know what Firebase is, it’s basically a cloud database hosted by Google. It’s free to use for applications that have less than 100 concurrent connections, which is enough for small applications. To get started with Firebase go to https://console.firebase.google.com/u/0/. Click the + to create a new project. Give it a name and a region. We will use the Real-time Database because Cloud Firestore is still in Beta. Select the ‘Start in test mode’ radio button and click ‘ENABLE’. These settings can be changed at any time in the Rules tab of the database. For now, we will ignore the error message that says: ‘Your security rules are defined as public, anyone can read or write to your database’. Let’s populate it with some random data. You can do this by hovering over the name of your database, and sign-here in my casecon by clicking the + sign.
Install the module:
$ npm install firebase
Now, we have connected to the database that we just created. But, the firebase package needs credentials. You can find these by clicking the gear icon on the left side of the firebase console. Next, click ‘Project settings’. Make a new file called config.js and add this to the file:
import firebase from 'firebase'
import firebaseSecrets from './firebaseSecrets'
const config = {
apiKey: firebaseSecrets.apiKey,
authDomain: firebaseSecrets.authDomain,
databaseURL: firebaseSecrets.databaseURL,
projectId: firebaseSecrets.projectId
};
const fire = firebase.initializeApp(config);
export default fire;
In the file above the secret credentials are imported from a file called firebaseSecrets.js. Let’s create that file and add this to our file:
module.exports = {
apiKey: "your-api-key",
projectId: "your-project-id",
authDomain: "your-project-id.firebaseapp.com",
databaseURL: "https://your-project-id.firebaseio.com"
};
Make sure to change the values in the firebaseSecrets.js file to your credentials. You should keep these credentials private. To do this go to the file .gitignore and add the line: firebaseSecrets.js. The next time you upload your code to GitHub it won’t upload our secrets.
Push data to Firebase. Change the App.js file to the following:
import React, { Component } from 'react';
import {
StyleSheet,
View,
} from 'react-native';
import {
Text,
Item,
Label,
Input,
Button,
} from 'native-base';
import firebase from './config'
import Form from 'react-native-form'
export default class App extends Component{
constructor(props) {
super(props);
this.state = {
};
this.itemsRef = firebase.database().ref().child(`people`)
}
pushToFirebase() {
let formValues = this.refs.soulForm.getValues()
this.itemsRef.push(formValues)
}
render() {
return (
<View style={styles.container}>
<Text style={styles.title}>
Sell your SOUL to the devil
</Text>
<Text style={styles.text}>
All you have to do is sign here
</Text><Text></Text><Text></Text>
<Form ref="soulForm" style={styles.form} >
<Item floatingLabel style={{marginTop:10}}>
<Label style={{marginLeft: 15}}>First name</Label>
<Input style={{marginLeft: 25}} name="firstName" type="TextInput" />
</Item>
<Item floatingLabel style={{marginTop:10}}>
<Label style={{marginLeft: 15}}>Last name</Label>
<Input style={{marginLeft: 25}} name="lastName" type="TextInput" />
</Item>
<Item floatingLabel style={{marginTop:10}}>
<Label style={{marginLeft: 15}}>Signature</Label>
<Input style={{marginLeft: 25}} name="signature" type="TextInput" />
</Item>
<Button Block primary onPress={() => this.pushToFirebase()} style={styles.button}><Text>Sell it</Text></Button>
</Form>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
title: {
fontSize: 30,
textAlign: 'center',
margin: 10,
},
text: {
textAlign: 'left',
color: '#333333',
marginBottom: 5,
},
form: {
width: '80%'
},
button: {
margin: 10
}
});
In this step, we imported Firebase and added a function which uses our Firebase setup to upload data to the cloud. Populate the fields, hit the sell button and go to the database tab of your Firebase project to see whether your data is uploaded.
$ git add .
$ git commit -m "Step 4: Adding Firebase"
$ git push origin master
So far, we did the basic setup of the app which is very important. The 5th step is the last one. It will get intense, but I know you can do it. Stretch your fingers and keep going!
Import React Native Signature Pad to capture the actual signature.
$ npm install --save react-native-signature-pad
I ran into a little problem with this module. If you also run into issues spend a little time on Google and you will find the answer. To become a great programmer the most important skill is knowing how to use Google. So, either practice your Google skills or copy the solution I found:
1.Open the file .\node_modules\react-native-signature-pad\index.js
2. Change the first line to this:
import React, { Component } from ‘react’;
3. And add this line below it:
import PropTypes from ‘prop-types’;
The signature module should work now. To test this let’s add a signature field to the form. And at the same time modify the pushToFirebase function in order to upload the signature.
import React, { Component } from 'react';
import {
StyleSheet,
View,
} from 'react-native';
import {
Text,
Item,
Label,
Input,
Button,
} from 'native-base';
import firebase from './config'
import Form from 'react-native-form'
import SignaturePad from 'react-native-signature-pad'
export default class App extends Component{
constructor(props) {
super(props);
this.state = {
signature: "",
isSoulSold: false
};
this.itemsRef = firebase.database().ref().child(`people`)
}
pushToFirebase() {
let formValues = this.refs.soulForm.getValues()
formValues.signature = this.state.signature
if(formValues.firstName === "" || formValues.lastName === "" || formValues.signature === "") {
console.log("Not all fields in the form are populated.")
} else {
this.itemsRef.push(formValues)
this.setState({
isSoulSold: true
})
}
}
signaturePadChange(base64DataUrl) {
this.setState({
signature: base64DataUrl
})
}
signaturePadError(error) {
console.error(error);
}
render() {
return (
<View style={styles.container}>
{this.state.isSoulSold ? <View style={styles.formContainer}><Text>There is no way back...</Text></View> :
<View style={styles.formContainer}>
<Text style={styles.title}>
Sell your SOUL to the devil
</Text>
<Text style={styles.text}>
All you have to do is sign here
</Text><Text></Text><Text></Text>
<Form ref="soulForm" style={styles.form} >
<Item floatingLabel style={styles.item}>
<Label style={styles.label}>First name</Label>
<Input style={styles.input} name="firstName" type="TextInput" />
</Item>
<Item floatingLabel style={styles.item}>
<Label style={styles.label}>Last name</Label>
<Input style={styles.input} name="lastName" type="TextInput" />
</Item>
<View style={styles.signature}>
<Label style={styles.signatureLabel}>Signature</Label>
<SignaturePad
onError={(error) => this.signaturePadError(error)}
onChange={(sig) => this.signaturePadChange(sig)}
style={styles.signaturePad}
/>
</View>
<Button Block primary onPress={() => this.pushToFirebase()} style={styles.button}><Text>SELL IT</Text></Button>
</Form>
</View>}
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#F5FCFF',
},
formContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
title: {
fontSize: 30,
textAlign: 'center',
margin: 10,
},
text: {
textAlign: 'left',
color: '#333333',
marginBottom: 5,
},
form: {
width: '80%'
},
signature:{
width: '100%',
height: 150,
},
signaturePad: {
flex:1,
margin: 10,
backgroundColor: '#eee',
},
button: {
margin: 10
},
label: {
marginLeft: 15
},
input: {
marginLeft: 25
},
item: {
marginTop:10
},
signatureLabel: {
marginLeft: 15, marginTop: 15
}
});
As you can see that the Signature module returns a base64 encoded string. In a few moments, I’ll show you how to decode it. The app will now look like this
Don’t click the ‘SELL IT’ button! Don’t do it! Unless you are really sure…
Did you do it? If you did, you might as well check the signature out on Firebase. Head over to the console. Go to your Firebase project and select the database tab. Here you’ll see a few tabs, open all of them to see the data you entered in the app. Under the signature tab, you’ll find a base64DataUrl, that’s the signature you drew. Copy the data URL and paste it in any base64decoder. Do you see the signature you entered?
The final step to finish the project is to submit our latest edits to Github.
$ git add .
$ git commit -m "Step 5: Adding signatures"
$ git push origin master
Finally, we have created a sign form successfully with React Native and Firebase and copied our code to the GitHub repository. You can make this app even more interesting by taking up challenges on your own for example show the signature after you clicked the ‘SELL IT’ button.
Thank you for reading this tutorial all the way to the end. Here is the URL for the source code: https://github.com/antonderegt/sign-here
Leave a Reply
Your email address will not be published. Required fields are marked *