Advanced Cloud Code

Create a Node.JS App using Cloud Code and Web Hosting

Introduction

This section explains how you can setup a subdomain and easily host static pages, after completing this step-by-step you will be able to use a Node.JS App to Register and Login Users.

Prerequisites

To complete this tutorial, you will need:

  • If you want to test this App first locally, you will need a local environment with Node.js installed to create a new website. You can follow the Official NodeJS tutorial to successfully install Node.js at your terminal.
  • An app created at Back4App.
  • Back4App Command Line Configured with the project.

First off, we need to talk about our new simple application!

We’ll describe an example about the usage from Web hosting! Let’s imagine that when we use Back4App as BaaS, sometimes we need to show a little presentation from the App created, with the steps below, you will be able to host a live Node.JS App.

At any time, you can access the complete Project in Back4App on this link.

Understand our final structure

Firstly, after completing the setup using the Command Line Interface (see prereqs), we’ll understand how it will work with the final structure from the files:

├── NodeJSWebApp/
│  ├── cloud/
│  │   ├── app.js
│  │   ├── routes.js
│  │   ├── package.json
│  │   ├── views/
│  │   │   ├── head.ejs
│  │   │   ├── index.ejs
│  │   │   ├── reset_password.ejs
│  ├── public/
│  │   ├── images/
│  │   ├── css/
│  │   │   ├── style.css

Step 1 - Enable your subdomain name on Back4app

Now, to enable your Web Hosting feature, after log in to your Back4App account, find your app and click on Server Settings, then find the “Web Hosting and Live Query” block and click on Settings. The “Web Hosting and Live Query” block looks like this:

Now, you just need to insert a available subdomain (feel free to choose any name) and click on Button to Save, like the example created below:

Step 2 - Create and upload files

In this step, is recommendable that you use Command Line Tool (see prereqs) to upload your files easily!

First off, we’ll create our files, called as: app.js and package.json inside the cloud directory!

In your terminal, inside the cloud folder, need to write:

$ touch package.json

Insert the npm module ‘body-parser’ inside the file package.json:

1
2
3
4
5
{
  "dependencies": {
    "body-parser": "*"
  }
}

Troubleshooting: Not is necessary to run npm install inside the cloud folder, the Back4App server will install it automatically!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Require the module
var bodyParser = require("body-parser");

// Set up the views directory
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');

// Set up the Body Parser to your App
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true})); 

//Require the routes.js file

require('./routes');

Step 3 - Create the views to your App

We’ll provide template EJS files to make the template App, feel free to change it in your side :)

Returning to the terminal

Inside the Cloud directory, it is necessary to create the views folder and the following EJS files:

  • head.ejs - We will use to insert the content to head from HTML structure.
  • index.ejs - Screen to Register and Log in user.
  • reset_password.ejs - Screen to the user request the Password Reset.

Hint: We will construct the views using Bootstrap, click here to read more about it.

You can insert the content to your respective views, feel free to use the templates below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  <title>Back4App - Node.JS Application</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="shortcut icon" type="image/png" href="/favicon.png"/>
  <!-- Bootstrap CSS--> 
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

  <!-- jQuery--> 
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

  <!-- Bootstrap JS--> 
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>

  <!-- Stylesheet Pages -->
  <link rel="stylesheet" type="text/css" href="/css/style.css">
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
  <!DOCTYPE html>
  <html>
  <head>
    <% include head.ejs %>
  </head>
  <body>
    <section id="header">
      <div class="container">
        <div class="row">
          <div class="col-sm-6">
            <div class="box-settings box-register">
              <div class="wrap-login100">
                <form class="validate-form" method="POST" action="/users/register">
                  <h2 class="title-screen">
                    Register a new account
                  </h2>
                  <div class="form-group">
                    <input type="text" name="usernameRegister" placeholder="Username" class="form-control" value="<%= infoUser.usernameRegister %>">
                  </div>
                  <div class="form-group">
                    <input type="text" name="emailRegister" placeholder="Email" class="form-control" value="<%= infoUser.emailRegister %>">
                  </div>
                  <div class="form-group">
                    <input type="password" name="passwordRegister" placeholder="Password" class="form-control" value="<%= infoUser.passwordRegister %>">
                  </div>
                  <% if (RegisterMessage != 'undefined' ? RegisterMessage  : '' ) { %>
                    <div class="alert alert-<%= typeStatus %>" role="alert">
                      <p><%= RegisterMessage %></p>
                    </div>
                  <% } %>
                  <div class="form-group">
                    <button class="btn-login btn">
                      Register
                    </button>
                  </div>
                </form>
              </div>            
            </div>
          </div>
          <div class="col-sm-6">
            <div class="box-settings box-login">
              <div class="wrap-login100">
                <form class="validate-form" method="POST" action="/users/login">
                  <h2 class="title-screen">
                    Access your account
                  </h2>
                  <div class="form-group">
                    <input type="text" name="usernameLogin" placeholder="Username" class="form-control" value="<%= infoUser.usernameLogin %>">
                  </div>

                  <div class="form-group">
                    <input type="password" name="passwordLogin" placeholder="Password" class="form-control" value="<%= infoUser.passwordLogin %>">
                  </div>
                  <% if (loginMessage != 'undefined' ? loginMessage  : '' ) { %>
                    <div class="alert alert-<%= typeStatus %>" role="alert">
                      <p><%= loginMessage %></p>
                    </div>
                  <% } %>
                  <div class="form-group">
                    <button class="btn-login btn">
                      Login
                    </button>
                  </div>

                  <div class="text-forgot">
                    <a href="/users/forgot-password">
                      Forgot Password? Click here to retrive your access!
                    </a>
                  </div>
                </form>
              </div>            
            </div>
          </div>
        </div>
      </div>
    </section>
  </body>
  </html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
  <!DOCTYPE html>
  <html>
  <head>
    <% include head.ejs %>
  </head>
  <body>
    <section id="header">
      <div class="container">
        <div class="row">
          <div class="col-sm-offset-3 col-sm-6" align="center">
            <div class="box-settings box-password">
              <div class="wrap-login100">
                <form class="validate-form" method="POST" action="/users/forgot-password">
                  <h2 class="title-screen">
                    Retrieve your access
                  </h2>
                  <p>Insert your email address</p>
                  <div class="form-group">
                    <input type="text" name="email" placeholder="Email" class="form-control" value="<%= infoUser.email %>">
                  </div>
                  <% if (resetPass != 'undefined' ? resetPass  : '' ) { %>
                    <div class="alert alert-<%= typeStatus %>" role="alert">
                      <p><%= resetPass %></p>
                    </div>
                  <% } %>
                  <div class="form-group">
                    <button class="btn-login btn">
                      Reset Password
                    </button>
                  </div>
                </form>
              </div>            
            </div>
          </div>
        </div>
      </div>
    </section>
  </body>
  </html>

Step 4 - Create the routes to render the views

First off, we need to configure the Routes to render the view created previously, the routes will be built using Express.

1
2
3
4
5
6
7
8
// Index
app.get('/', function(req, res) {
    res.render('index', {loginMessage: '', RegisterMessage: '', typeStatus: '',  infoUser: ''});
});
// Request Password
app.get('/users/forgot-password', function(req, res) {
    res.render('reset_password', { resetPass: '', typeStatus: '', infoUser: ''});
});

Hint: As you can see, we are configuring variable as parameters that will be used to display alerts on the page. Follow the next step!

Step 5 - Create the routes to save the informations to your database

We will use the Parse Server Javascript Guide as a parameter for the development of our functions to Register, Login and Request the Password.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// Request the Log in passing the email and password
app.post('/users/login', function(req, res) {
    var infoUser = req.body;
    
  Parse.User.logIn(infoUser.usernameLogin, infoUser.passwordLogin, {
      success: function(user) {
        res.render('index', { loginMessage: "User logged!", RegisterMessage: '', typeStatus: "success",  infoUser: infoUser});
      },
      error: function(user, error) {
        res.render('index', { loginMessage: error.message, RegisterMessage: '', typeStatus: "danger",  infoUser: infoUser});
      }
  });

});

// Register the user passing the username, password and email
app.post('/users/register', function(req, res) {
    var infoUser = req.body;
    
  var user = new Parse.User();
  user.set("username", infoUser.usernameRegister);
  user.set("password", infoUser.passwordRegister);
  user.set("email", infoUser.emailRegister);

  user.signUp(null, {
    success: function(user) {
      res.render('index', { loginMessage : '', RegisterMessage: "User created!", typeStatus: "success",  infoUser: infoUser});
    },
    error: function(user, error) {
      res.render('index', { loginMessage : '', RegisterMessage: error.message, typeStatus: "danger",  infoUser: infoUser});
    }
  });
});

// Request the Password reset passing the email
app.post('/users/forgot-password', function(req, res) {
    var infoUser = req.body;
    
  Parse.User.requestPasswordReset(infoUser.email, {
    success: function(user) {
      console.log(user);
      res.render('reset_password', { resetPass: "Check your email!", typeStatus: "success", infoUser: infoUser});
    },
    error: function(error) {
      res.render('reset_password', { resetPass: error.message, typeStatus: "danger", infoUser: infoUser});
    }
  });
});

Step 6 - Almost there! Static files in public folder

It’s not over yet, in the public folder, you can insert some static files as CSS and images to require this on the views :)

Step 7 - It’s done!

At this point, you have learned how to get started with Node.JS Applications using Cloud code.

At any time, you can access the complete Project in Back4App on this link.

With the guide described above, you’re able to work with the Web Hosting to use a Node.JS application!