Firebase

Firebase is an application development platform by Google and consists of a suite of products geared towards quick development and business growth. In this lab we shal, implement firebase auth, save data in the fire store and deploy an application to firebase hosting.

Task 1

We shall make use of gitpod as our environment due to the access of the terminal needed for this lab.

Open Gitpod Workspace

This is based on this repo, you can also try this lab in codespaces on github.

Once you have a gmail account you can create a firebase project by clicking the following link.

Create Firebase Project

Task 2

Click on a new project, then enter a name. You can skip setting up google analytics and finish the setup. After creation you will then be directed to the project dashboard.

Next add a web app to the project by clicking the web icon.

Name your app and domain

Now copy your firebase config, create a firebaseConfig.js file in the public folder of your workspace pasting your sdk config into it as follows

public/firebasaConfig.js

const firebaseConfig = {}; //paste your config object in here

export default firebaseConfig

You have just linked your firebase project to your code.

You can return to the browser and finalize the setup by clicking next, next then "Continue to console"

The firebase-cli has already been installed in the gitpod workspace to login first open up a new terminal from the toolbar.

Task 3

Execute the following command in the terminal.

firebase login --no-localhost

The --no-localhost flag is required as we are running this via the cloud in gitpod. Answer ‘y' if asked to collect CLI usage. Then ctrl + click the link given in the terminal.

The link would take you to a sign-in page. Sign in with the same google account used to create the project then click allow. It should then give a code which you will need to copy (ctrl +c) and paste into the gitpod terminal (ctrl + shift + v or right click).

Press enter after pasting then you should be logged into the CLI.

Next you need to initialize the workspace as a firebase project then you would be able to deploy.

Task 4

Type and run the following command in the terminal.

firebase init

On the following menu use the down arrow key to highlight hosting and tap the spacebar to select it then press enter.

Then select "Use an existing project".

Then select the project you created on the firebase console.

Press enter for the remaining prompts.

Firebase should finally be initialized.

If you want to serve your website for development purposes.

Task 5

Type an run the following command

firebase serve

Firebase would start a development server on port 5000.

Gitpod would detect something is running on the port. To view the site click "Make Public" then press "Open Preview"

You can then view your site running right in gitpod!

Before you deploy to firebase ensure that all of your website's files are in the public folder, refresh the browser and ensure the served site is working.

Task 6

Because the serve command is still running in the terminal it is said to be ‘non-interactive'. You can open a new terminal or cancel the serve command by clicking into the terminal and pressing "ctrl + c".



Now execute the following command.

firebase deploy

You would be given a link to view your deployed application. Follow the link (ctrl + click) to see your application hosted for free over https!

This application makes a request to a dump of an api which is stored in books.json hosted in the same place as the app itself. This is a nice way to easily get data into your app.

However applications often have user generated content, whether it be media or data in the form of comments.

In order to achieve this we need a mechanism to identify which user is allowed to manage which content hence the need for authentication.

Task 7

To simplify things we shall use anonymous auth so users can log into a temporary profile with a single click. This will persist until they logout or reset their site data.

Click on get started on the Authentication tab of your console.

Select the Anonymous auth provider

Next enable the provider then click save.

Finally go to the setting in the auth tab, scroll down, click Authorized domains > Add domain and paste the url to your Gitpod Site not EDITOR (many of you will still paste the editor url) in the domain field then click add.


This will tell firebase to allow your gitpod site to login. Now you should be able to login by clicking the login button on the app.

This functionality is setup via the auth.js file. which imports your firebase config using a syntax called es6 imports then uses the firebase-auth sdk to create 3 functions:

Like in firebaseConfig.js we use es6 exports to export these functions and a firebase auth object that gives us information on the currently logged in user.

Taking a look at the script in index.js you can see how we attach the login/logout functionality as well as how the UI changes.

index.html

  
      import { signIn, logout, auth, setAuthListeners } from './auth.js';
      import { getBooks, getReviews, createReview, deleteReview } from './data.js';

      let loginBtn = document.querySelector('#loginBtn');
      let logoutBtn = document.querySelector('#logoutBtn');
      let reviewForm = document.querySelector('#reviewForm');

      function setLoggedInUI(){
          M.toast({html: 'Logged In!'})
          document.querySelector('#user').innerHTML = `Signed in Anonymously`;
          document.querySelector('#loginBtn').style.display = 'none';
          document.querySelector('#logoutBtn').style.display = 'inline-block';
      }

      function setLoggedOutUI(){
          M.toast({html: 'Logged Out!'})
          document.querySelector('#user').innerHTML = '';
          document.querySelector('#loginBtn').style.display = 'inline-block';
          document.querySelector('#logoutBtn').style.display = 'none';
      }

      //attatch listeners
      logoutBtn.addEventListener('click', logout);
      loginBtn.addEventListener('click', signIn);
      reviewForm.addEventListener('submit', submitReivew);
      setAuthListeners(setLoggedInUI, setLoggedOutUI);
//...

Finally we want to begin storing and retrieving user generated content. We will use firebase firestore which is a realtime noSQL database to store user created book reviews.

First go to the console and setup your database.

Create a database in test mode then click create

You can then return to the app, click on a book and try creating a review once you are already logged in.

Reviews should be saved and shown immediately on the ui. This is thanks to the code in data.js which uses the firebase-firestore sdk to create functions.

These functions are imported into index.html and some are attached as event listeners to various elements on the page.

selectBook() is a UI function that does 3 things:

  1. retrieves reviews for the selected book for displaying using getReviews() and renderReviews()
  2. set up the #reviewform to know what book we'd like to create a review by setting the value of a hidden input field called #selectedBook.
  3. displays the selected book above the review form.
      function selectBook(isbn, name){
          document.querySelector('#selectedName').innerHTML = name;
          let selectedBook = document.querySelector('#selectedBook');
          selectedBook.value =isbn;
          getReviews(bookId, renderReviews);
      }

subitReview() is our form submission event handler that uses createReview() to store the data in firestore then calls getReviews() to show the updates.

reviewForm.addEventListener('submit', submitReivew);

async function submitReivew(event){
    event.preventDefault();
    let form = event.target;
    let formData = new FormData(form);
    const { text, isbn } = Object.fromEntries(formData);
    if(isbn === 'null'){
        alert('Please select a book to review');
    }
    else if(auth.currentUser === null){
        alert('Please login to review');
    }else{
      await createReview(auth, isbn, text);
      M.toast({html: 'Review created!'});
      form.reset();
      getReviews(isbn, renderReviews);
    }
}

Note it sends the auth object to createReview() so we can record the author. However because we are using anonymous auth it will be anonymous, if you use another authprovider you can show the actual users username instead.

In the firestore you can see your data that was submitted.

This concludes a considerable crash course in the firebase platform. Note it offers many features like uploads, notification, machine learning etc. You are free to check their documentation if you wish to use the free features for your project.

References & Additional Reading