Overview

Our goal is deploy AddressMaven to Firebase hosting.

Get Started

Go through the steps in the Firebase Starter project to create a second project in the Firebase console. This time, call the project AddressMaven-Lastname where Lastname is your last name.

Create a new directory in your repository called FirebaseAddressMaven. Run firebase init in there and complete any other related steps from the Firebase Starter assignment.

Copy files

Run these commands from the root of your FirebaseAddressMaven project. First create a symbolic link to make it easier to find your repository. Then copy some directories with rsync:

ln -s ~/Git/prog272-lastname-2019/ ~/p2c
rsync -avzh ~/p2c/AddressMaven/source .
rsync -avzh ~/p2c/AddressMaven/public/stylesheets public/.
rsync -avzh ~/p2c/AddressMaven/views functions/.

There are also a few individual files that we can copy over:

cp -vp ~/p2c/AddressMaven/webpack.config.js .
cp -vp ~/p2c/AddressMaven/.babelrc .
cp -vp ~/p2c/AddressMaven/routes/address-list.json functions/.

Create package.json

In the root of our Firebase project, create a package.json file that looks something like this:

{
    "name": "address-maven",
    "version": "0.0.0",
    "private": true,
    "scripts": {
        "start": "npx webpack --watch & firebase serve",
        "build": "npx webpack"
    },
    "dependencies": {
        "@babel/cli": "^7.4.4",
        "@babel/plugin-proposal-class-properties": "^7.4.4",
        "@material-ui/core": "^3.9.3",
        "@material-ui/icons": "^3.0.2",
        "file-loader": "^3.0.1",
        "react": "^16.8.6",
        "react-dom": "^16.8.6"
    },
    "devDependencies": {
        "@babel/core": "^7.4.4",
        "@babel/preset-env": "^7.4.4",
        "@babel/preset-react": "^7.0.0",
        "babel-loader": "^8.0.5",
        "webpack": "^4.30.0",
        "webpack-cli": "^3.3.1"
    }
}

Except for the start script, everything in this file also appears in our original AddressMaven project. The difference is that we have deleted bits that we will not use or will move into the functions directory. In particular, we have removed the testing, at least for now. This is because we are assuming we are deploying exactly the same front end in AddressMaven as we will deploy here. So we can do our testing in AddressMaven, and then copy over any changes with this command:

rsync -avzh ~/p2c/AddressMaven/source .

Create Bundle

Run npm install and then npx webpack. This should create bundle.js and put it in the public directory.

Move Functions

In AddressMaven, in the routes/index.js file, we have a number of functions that run on the server. We will want to move these to our Firebase project and put them in the file called function/index.js. There are several steps involved in this process.

To get started, run these commands from the functions directory:

npm install express
npm install pug

Note that these packages end up being listed in functions/package.json not the package.json file in the root of our project. In other words, be sure you do this work in the functions directory.

Here is a simple starter version for our copy of functions/index.js:

const functions = require('firebase-functions');
const express = require('express');
const app = express();
const path = require('path');
const fs = require('fs');

app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');

app.get('/', function(req, res) {
    'use strict';
    res.render('index', { title: 'Elf-Express' });
});

app.get('/foo', (request, response) => {
    response.send({ result: 'success' });
});

exports.app = functions.https.onRequest(app);

Delete any default code generated by firebase init from index.js and replace it with the above. When working in this file, I believe we will always want the exports line to be the last line in the file regardless of any further modifications we make to it.

Also, modify the firebase.json file found in the root of your project so that it looks like this:

{
  "database": {
    "rules": "database.rules.json"
  },
  "hosting": {
    "public": "public",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [{
      "source": "**",
      "function": "app"
    }]
  }
}

Notice that we have added a rewrites property that refers all requests (**) that reach the server to our app.

You should now be able to launch your project and see the home page by issuing this command:

firebase serve

Working

You have probably noticed that you cannot navigate beyond the home page. To fix this, add in the worker route from AddressMaven/routes/index.js.

At least for now, when copying over code from index.js in AddressMaven to your firebase app, change router to app.

Not this:

router.get('/foo', (request, response) => {
    response.send({ result: 'success' });
});

But this:

app.get('/foo', (request, response) => {
    response.send({ result: 'success' });
});

After adding the worker route navigation via the menu and the button on the Go page should both begin to work.

Turn it in

Copy over the the /address-list route and your readFile promise into functions/index.js. The completed application should be able to display your list of addresses.

NOTE: If you were not able to get your program to display the addresses correctly for the midterm, then you won’t get them working correctly here either. Just be patient. I will grade your midterm and get you hints before I grade this assignment. Or perhaps you will see how to get things working over time. In other words, the point here is not to get everything working correctly, but to get your AddressMaven project, regardless of its current state, running on Firebase. That’s what you will be graded on for this assignment. Don’t worry that I will leave you stranded with a broken app over the long term, I won’t do that. But for now, just keep moving forward as best you can. Yet another way to state this whole matter: I can’t go to each student who has a bug during class and help them fix it. So if things are not working correctly just now, then keep moving forward as best you can, and we will get your code working eventually. Ask questions about Firebase, of course, but not about the midterm.

When you submit, tell me the directory where I should look for your project. After you push, tag your project and give me the tag. If you are using a branch, tell me about that as well.

Bower

I think several students are still using JQuery and Bootstrap in views/layout.pug. You should remove that code. These are the lines that need to be deleted:

link(rel='stylesheet', href='/bower_components/bootstrap/dist/css/bootstrap.css')
script(src="bower_components/jquery/dist/jquery.js")
script(src="bower_components/bootstrap/dist/js/bootstrap.js")