Angular + Firebase + Typescript — Step by step tutorial

A tutorial on starting to solve Free Code Camp’s “Book Trading” challenge

Update

Checkout my new Angular + Cloud Firestore (a “new version” of Firebase) article 😙.

In this tutorial we will use Angular and Firebase (with the mighty Typescript) to implement a real-time "Book Trading" web application

Working DEMO here! 🎠 Github repo here! 😙

The solution must adhere to the following user stories:

  • I can view all books posted by every user
  • I can add a new book to My Library
  • I can propose a trade and wait for the other user to accept the trade

At the same time, we will start to solve one of the challenges of the Free Code Camp’s back-end certification 🎉.

Firebase

For those who do not know Firebase is a Google product whose features can be summarized in the following sentence:

Firebase is a real-time NoSQL cloud database (but also cloud storage and messaging service and authentication service and — see here) that helps you build apps without building the backend (or letting you to add someone later — see functions). You can save and retrieve JSON objects, build user authentication, and get data updates in real-time across connected devices in milliseconds: data remains available if your app goes offline, providing a great user experience regardless of network connectivity.

Thus all we need to develop a mobile/web app, with a very short learning curve and a significant boost in development.

Firebase setup

Create a new Firebase app on your Firebase console with your Google Account by clicking on “Add project” and typing “fcc-book-trading”.

Then click on “Add Firebase to your web app”, and copy the config keys into src/environments/environment.ts(do the same for environment-prod.ts), the result should be similar to this (notice that these infos will be always available under Authentication tab then click on Web setupbutton on the upper-right corner):

The last thing is to enable anonymous access to your database in order to avoid building actual authentication (see the code on github to see how I solved this with the Google Sign-In):

Go to the Database tab, then Rules and change the rules in this way (please do not forget to publish them! Remember also to restore them when you will add the actual authentication 😅)

{
"rules": {
".read": "auth == null",
".write": "auth == null"
}
}

Okay, now everything is ready to use Firebase and implement our application.

Angular

Let’s proceed by creating a new Angular solution (always using the amazing Angular CLI)

npm i -g @angular/cli@latest //if not already installed
ng new fcc-book-trading

I’m a fan of observables and all APIs that provide a fluent notation: thus we will use the official Angular library for Firebase, i.e. angularfire2.

cd fcc-book-trading/
npm i firebase angularfire2

We will use Firebase with the help of the observables: these will allow us to have a responsive interface and to take full advantage of the realtime updates provided by this wonderful set of technologies.

Here’s an example of a simple component that shows a list of book objects provided in real-time by a Firebase database (copy and paste it in your src/app/app.module.ts):

Do not forget to import the AngularFireModule and AngularFireDatabaseModule in your app.module.ts

At this time you can start your project! Just do it with ng s in your console.

You will get an empty page 😤: it’s because the database does not contain any book… so let’s proceed with learn how to write and update our data (for those that can’t wait: try to go under Database tab, thenData and add a book node with something inside it 🍭).

In Firebase you can think of the database as a cloud-hosted JSON tree (see picture below): when you add data you’re simply adding a node to the tree with an associated key (specified by you or kindly generated by Firebase— with the push() function: notice that you should prefer the Firebase decreasing the query evaluation time).

For those who come from a relational database background, we can think to the first-level nodes of this tree (books in this case) like the old-fashioned tables. Here we are talking about lists of JSON objects instead of tables, using the push() function to add objects instead of rows to our real-time database.

As you can see from the screenshot the list books is populated by two objects that present the “body” of a book with the respective fields. Notice that Firebase is a NoSQL database, thus we would be free to save other “types” of objects in the same list, even if they are not books. Since we’re exploring this technology we will assume that every list contains only one “type of object”, but its interesting to highlight this feature (think about the chance to store data that changes shape over time, adding o removing fields 🎉).

Let’s try to perform our first write on the Firebase database (modify your src/app/app.component.ts)

Here we added a button and a simple method that pushes a new book in the books list: check the behavior of your solution and see if the new book is immediately published in the list. Now do the same with two or more instances of a browser: you will get an immediate update of the list in each instance 😎!


Firebase queries

Since Firebase always return an observable we could apply a chain of operators (map, filter, etc) to obtain the desired outcome: however it’s better to restrict large list of items directly by a specific query rather than delegate the client to synchronize the data and apply a filter.

Unfortunately, Firebase does not provide a suitable set of operators to compose and execute complex queries (see here the docs): in my opinion if Google invests in this domain this technology could become a set of killer APIs for the development of POCs/medium-small web-apps or for the rapid development of back-ends for mobile apps (see later Cloud Firestore vs Realtime Database).

We can try to import this sample JSON into the database to do some practice (just save the file and use the Firebase console import feature).

The structure is very simple: in the file you will find 3 books with an array of assigned authors. Let’s now imagine making a simple filter of available books by title: let’s add a button to filter the results and analyze the filter function code

As you can see, we have passed a query with the orderByChild operator by specifying to filter the field title for My book #1: after invoking the filterBooks function we will get a new instance of the list and an interface update (to avoid this unpleasant behavior and to use all the features provided by Angular properly — in my case I used Pipes & Observables synergy to get the result — checkout the repo here and here).

The good news unfortunately ends here! If we wanted to filter out the books made (in our example) by ‘John Doe’ we would discover one of the many Firebase limits: the inability to concatenate operators to make complex queries 😢. To reach the goal, we should expose the relationship between authors and books to another list, simplifying (but actually duplicating) the information to be filtered… but there is hope: checkout the Cloud Firestore vs Realtime Database and my article on Cloud Firestore 🎉!

Conclusions

In just a few steps, we have implemented an application that allows the insertion and updating of data in real time using Firebase. This technology embraces the intensive use of Observables, allowing for example to make a data filter that can change in real-time: for example, try to open the DEMO from two different browsers and try inserting and filtering at the same time.

Maybe next time I will deepen the interaction between Cloud Firestore, Observables and Pipes: but this is another story! Happy coding!