Welcome to my fourth tutorial of the series, in this tutorial we will go through the SQL required for the signup method on our API.

A pug, one of my favourite dogs.

First off I must admit I did make a minor mistake in my previous tutorial when defining the connection pool, you will need to assign the “createPool” function to a variable like the below so we can refer to it later in our API calls.

const myPool =   mysql.createPool({user:process.env.USER,password:process.env.PASSWORD,database:process.env.DATABASE,host:process.env.HOST,connectionLimit:10});

Now when a user goes to signup for an account to use a service we first need to check if the user already has already signed up, I usually do this via an SQL query selects the data from the user table where the email address sent in through the app form is equal to the email column in the database and get the count of this, if the email is found in the database that means the user has already signed, however, if no email address is found then we can assume this is a new user and we can go ahead with inserting the data given into the database. So something like the below.

select COUNT(*) FROM user where email = ?

Meanwhile, the first thing we need to do is remove the initial “res.send” we put in the “/signup” method and we need to use a method called “getConnection” which is part of the “mysql” package and can be used when you make an instance of the “createPool” value. So you should make your code look similar to what I have below.

If we were making just one query we could directly call “myPool.query” but since we are running multiple queries, one for checking the count and another for inserting we need to get a connection and then run the “query”.

We now need to create 2 variables that will represent the data passed into the body of the request.

var email = req.body.email;var password = req.body.password;

Put these variables above the “getConnection” method.

Now we need to use the “email” variable as a parameter to the first sql query to see if that email is present within the database “.query” has many parameters including a few callbacks. After writing something similar to the below you will need to enter a comma and write a pair of square brackets which surround the email variable. This tells the “query” that we want to pass in the “email” variable as parameter equal to where we have written “?” in the sql query.

myPool.query('SELECT COUNT(*) AS EmailCount FROM user WHERE email = ? 'myPool.query('SELECT COUNT(*) AS EmailCount FROM user WHERE email = ? ',[email]

There is now a final callback function that gets passed into “query” which has 3 parameters, an error parameter, results parameter and fields parameter we will be concentrating on the error and results parameters.

Inside of the query callback we can run an if statement on the error callback to do something if an error occured while selecting the count, if no error we can use the “results” parameter to extract the count value. So currently our signup method will look like the below.

We create 2 variables that are to the data passed into the body of the request. We then get a connection from the connection pool, do an error check, if no errors we then run a query to select the count of emails that are equal to the email data passed into the body of the request. Within the callback of the “query” we then do another error check and if no error occurs we create a variable that is equal to the first result set of the query and get the column/data returned which in this case is “EmailCount”.

We will now do an if statement on the emailCount variable and if it is 1 then we send a response message to say this email address is already associated to an account on the system else we will carry on with hashing our password and inserting the data into the table.

So our next step is to take the password that was sent in the body of the request and hash it so the password is not stored as plain text, we will do this using the “bcrypt” package. “Bcrypt” has a built in method called “hash” which enables you to put the password you want to secure as the first parameter and the number of salt rounds you want to implement on the password as the second parameter, there is a final callback function on this method.

A salt round can be seen as a “cost” factor meaning that a cost factor controls how much time is required to calculate a bcrypt hash so the higher the salt rounds the longer it will take for brute force attacks to break the hashed password usually the salt round is set to 10 or 11 in bcrypt.

We must now create a variable called “saltRounds” which is equal to 10 and put this as the second parameter of the “hash” function with the first parameter being the password variable we created. Your code should look similar to the below.

var emailCount = results[0].EmailCount;if (emailCount === 1) {res.send({message: 'This email address is already associated with an account'})} else {var saltRounds = 10;bcrypt.hash(password, saltRounds, function (err, myHash) {myPool.query('INSERT INTO user(email,password,isActive)VALUES(?,?,1)', [email, myHash], function (err, insertResults, insertFields) {});});}

So within the code above we are doing an if statement to check if the email count is 1, if so send response, else create salt rounds variable and hash the password so it is unreadable, within the callback function we then run a second query to insert the email, password and isActive data to the database.

Inside of this query we then do another error check and if there is no error when inserting we send a response back to the user to say a user has been inserted.

if(err){console.log(err + ' when inserting data into db');}else{res.send({message:'User inserted!'});}

Once you have written that you will need to do the typical git add, commit and push, then go to postman and run your API link with “/signup” at the end with a json object as the body with keys of “email” and “password”.

There you go! I have just ran my API link through postman and passed in “email” and “password” as body data and the data has been inserted into my database! But we all know to insert a user we would not use postman we want to use our app!.

So now go back to your react-native app and open the “signup.js” file, we need to make a function that will set the state of the email and password values a while ago I would write 2 functions for this but I found a really cool way (from another guys Medium article of course) of doing it all in one.

Create a function called “customStateSet” with 2 parameters “stateKey” and “stateValue”. Inside the function write the below.

this.setState({[stateKey]:stateValue});

The above basically sets the state of whatever value was set as the state key in the function parameter.

So in the text input for “email” we need to add the “OnChangeText” to this component which is ran when the text inputs text changes and the text value is passed in as parameter to the “onChangeText” so we need to pass in the the text from the text input into the function parameter as well as the key of the state.

So now our email TextInput component will look like this

<TextInput autoFocus value={email} style={{borderColor:'black',borderBottomWidth:1,width:100}} onChangeText={(event)=>this.customStateSet('email',event)} />

Our password TextInput component will look like this

<TextInput value={password} style={{borderColor:'black',borderBottomWidth:1,width:100}} onChangeText={(event)=>this.customStateSet('password',event)} />

When you have done this you need to go back to your “Signup” function and make sure it looks similar to the below. So we are destructuring the state, creating a json string of the data and passing that data to the body of the signup request. We also need to add headers to our request and set the content type to “application/json”

Signup = () =>{const {email,password} = this.state;const myData = JSON.stringify({email:email,password:password});axios({method:'POST',url:calls.signup,data:myData,headers:{'Content-Type':'application/json'}});}

One of the two final things to do is to add a visual response to the user when they have added a user so to create a response after the axios we need to add a promise which will contain the response that was set in the API and we set a response of “message” so we just then have an alert that contains the “message” data.

axios({method: 'POST',url: calls.signup,data: myData,
headers:{
'Content-Type':'application/json'}}).then(response => {alert(response.data.message);});

Our final thing to do is to add a click event to the “Signup” touchable opacity that will run the Signup function when clicked so now our touchable opacity will look like the below!

<TouchableOpacity style={{ backgroundColor: '#42C0FB' }} onPress={()=>this.Signup()}><Text style={{ textAlign: 'center', padding: 15, fontSize: 20, color: 'white' }}>Signup</Text></TouchableOpacity>

One thing I have forgotten to do is to add a “secureTextEntry” to the password field so our password is not visible.

<TextInput secureTextEntry value={password} style={{ borderColor: 'black', borderBottomWidth: 1, width: 100 }} onChangeText={(event) => this.customStateSet('password', event)} />

As you can see from the screenshot below I have entered a test email and the response returned is that the user has been inserted into the database I shall have a look to see if this is the case.

As you can see that email has been entered into the database and we can now sign up a user from our react-native app.

In a real use case you would most likely have some sort of email verification where you send an email to a user with a unique link and when that link is clicked an API endpoint is activated which updates a column in the user table which is unique to that user but I thought that was out of scope for this tutorial series.

Thank you for reading this far, this article took me a few hours to write so I would really appreciate if you could like/share and give me feedback on what you liked/disliked

Have a nice day :)

Check out my blog — https://cowboycode.co.uk/

--

--