by Zdravko Kolev

How to build a Firebase Angular app with auth and a real-time database

6iOFygx9cGm7rGROEFkCCY1y4kxi6SBDKrpi

For a long time, I was looking for a good Portfolio web app that can help me to easily track my Cryptocurrency profits/losses until I’ve decided to develop such on my own with the help of Firebase and Angular! Yes, it’s that easy, let me explain to you why.

Firebase gives the perfect tooling for applications with user authentication and Real-time database storage needs. It provides rich documentation with a variety of dev examples to help anyone gain a better understanding of how to create stellar apps.

I have covered the Angular application bootstrapping, using Ignite UI CLI, in another blog post.

This article aims to:

Configure a Firebase account

I want to go through the steps that we’ve taken to set up the Portfolio Firebase account. Projects are created from the Firebase console by choosing Add a new project. Once the Create project form is submitted you will see the following Project Overview.

NasIpLrw4HFk-0GPRJgygDdFbFUJFCyj3ZlC
Firebase Project Overview

Under the Project Overview section, you can find all development tools that are used for Authentication and Data storing. Here is also located the configuration which is used in the Portfolio Web App. This configuration is generated by pressing Add Firebase to your web app, and it is later added in application’s app.module.ts file.

Let’s get back to the sidebar on the left and select Authentication. From here we have access to the Sign-in methods that we need in the app. Navigate to the Sign-in tab, there you can see the providers that are enabled and used in the Portfolio application — Google, Facebook and Email/Password provider.

Sign-in providers let users authenticate with Firebase using their Facebook and Google accounts by integrating their logins into the app. As for the Email/password provider, it represents a simple authentication mechanism by using only email and password. Firebase Auth provides built-in validation rules verifying the user entries, so we don’t need to configure something additional here.

tLYYAMF7mIhAghwLl17dLrIc1pPLXFLtQxbX

The “trickiest” part here was the Facebook provider configuration because we needed to have a Facebook application in order to authenticate the login. We’ve created a FB app from Facebook Developers which provided us with the App ID and App Secret requested from Firebase.

BM7Zm2-pKYb1f2W1dpeA9Kxh7qfJVAtRvHEj

Both API ID and Secret should be filled when enabling the Facebook provider. As for the Auth redirect URI (from the provider window) it should be pasted under Facebook/Facebook Login/Products section/Valid Auth Redirect URIs.

Let’s continue with the Firebase console. From the Database view page, we’ve created a Real-time Database.

7nr-cSrLC1cCSldefkhHzdMjK5MVrp1gjJeF
Firebase Database View

In this view, we can find information about the application data items and write/read security rules. Below are the rules used by the Portfolio application:

{  "rules": {    "items": {      "$uid": {        ".read": "$uid === auth.uid",        ".write": "$uid === auth.uid"      }    }  }}
This Security Rule configuration will allow only authenticated users to be able to read and write in our database. If you want to learn how to define more advanced rules, I strongly recommend checking out the Official Security & Rules section.

Okay, where were we? Now that we’ve gone through the Portfolio Firebase account creation, let’s see how the Firebase development project was created.

If we didn’t have a project created already, I would have recommended starting with installing the firebase CLI, that provides a variety of tools for managing and deploying Firebase projects. BUT we’ve bootstrapped the Portfolio Angular Project with Ignite UI CLI, so we just needed to install AngularFire and Firebase from npm. We need both packages in order to communicate with Firebase. AngularFire is the official library for Firebase and Angular development.

npm install firebase @angular/fire --save

All AngularFire modules that are used in the application are added in the app.module.ts file:

  • FirestoreModule is needed for the database features like working with collections, queries, and services for data streaming and manipulation.
  • FireAuthModule is needed for authentication features like monitoring authentication state, Log-in providers and security.
  • FireDatabaseModule allows us to work with Realtime databases. It’s very efficient for mobile and web apps that require synced states across clients in Realtime.
The only common module that is not used in the Portfolio app is AngularFireStorageModule. You can use this module to quickly and easily store and serve user-generated content like photos and videos as well as monitor uploads and metadata associated with files.

Now that we know how the app was configured initially, we can take a look at the other Firebase features that are used.

Authentication

We use AngularFireAuth service to monitor the app authentication state. AngularFireAuth.auth returns an initialized firebase.auth.Auth instance, allowing us to log users in and out. The app demonstrates Sign-in capabilities using three providers: Facebook, Google, and Email.

Firebase user instance is kept for every provider linked to the user, and when a user is registered or signs in, that user becomes the current user of the Auth instance. The instance persists the user’s state so that refreshing the page or restarting the application doesn’t lose the user’s information.

We use signInWithRedirect method for both Facebook and Google providers, in order to sign in by redirecting to the sign-in page. Password-based account creation is used for the Email sign-in provider, createUserWithEmailAndPassword and signInWithEmailAndPassword are the methods responsible for the user account creation and sign-in.

Un3vsdL0fp6UFYRhxs7LJxUamWku00-0zOdc
Password-based account view

I recommend the official Firebase docs for more detailed information on authentication and user lifecycle.

Real-time Database Actions

Firebase offers two cloud-based, client-accessible database solutions, and we are using Firebase’s original database — Realtime. Check out the differences between Realtime and Cloud firestore on the official documentation page.

AngularFireDatabase and AngularFireList services are used in the Portfolio app to retrieve, save and remove data easily.

AngularFireDatabase can be injected through the constructor of a component or @Injectable() service. In our case we use the second approach:

Data is retrieved through the AngularFireDatabase service, which fills Observable list of BlockItems. AngularFire provides methods like snapshotChanges() that returns Observable of data as a synchronized array. It is very handy if you want to limit event actions, like added, changed, removed and moved. By default, it listens to all four, however, you may only be interested in one of these events and you can specify which of them you’d like to use. In our application, we are subscribed to all of them.

Adding a new item, updating an existing one, or removing it from the list is achieved by using push(), update() and remove() methods.

Each data operation method returns a promise, although we don’t need to use the completion promise to indicate success because the real-time database keeps the list in sync.

Observables

CoinItem service

Cryptocompare API service manages async data and emits multiple values at a time with Observables. We use HttpClient get()method to request the data from the resource and subscribe to it, in order to transform it to Observable Array of CoinItem objects, which will be used later by our igxGrid, igxList, and igxCard components.

Rx.js allows us to cache the result of the HTTP Request. We retrieve this data initially, cache it and use the cached version during the application’s lifetime. The combination of publishReply(1, 300000) and refCount() does the following.

publishReply(1, 300000) tells Rx to cache the latest emitted value and to stay valid for 5 minutes. After that time, it will invalidate the cache.
refCount() tells Rx to keep the Observable alive as long as there are any Subscribers.

Now after we subscribe to the Coins list, the result will be cached, and we won’t need to make another HTTP Request.

BlockItem service

Portfolio Crypto Coins data is ensured by getItemsList() method that returns Observable BlockItem array to which the igxGrid component is subscribed to. Only authenticated users can use this service because of the AngularFireList that we manipulate is associated with unique user ids.

Visualize the data

For the visualization, we use UI Components from the Ignite UI for Angularlibrary. These components are responsible for data handling while providing access to custom templates and real-time updates, with intuitive API, by using minimal amount code.

igxGrid

Grids [data] property binding is used to pass the returned BlockItem array. Each <igx-column> represents a field of the object and it is used to define features like editing and sorting. The columns are templatable, and with the help of Angular pipes, we can declare display-value transformations in them easily. We use a decimal pipe to change the minimum number of integer digits before the decimal point.

The component provides straightforward event handlers and API for CRUD operations. Handlers like updateRow and deleteRow are implementing additional logic like AngularFireList manipulation and coin item restore logic with the igxSnackbar.

igxCard

Cards are used to provide general information of Crypto coins using CSS Flexbox layout. These Card components can be filtered with the igxFilter directive, which can be used to filter different data sources. igxFilter can be applied as a pipe or as a directive.

igxFinancialChart

The Chart offers multiple ways in which the data can be visualized and interpreted, once it is returned by the service. There are several display modes for price and volume, and in our case we use chartType=”candle”.

The financial chart component analyzes and selects data columns automatically:
- Date/Time column to use for x-axis
- Open, High, Low, Close, Volume columns or the first 5 numeric columns for y-axis

Theming

IgniteUI for Angular bases its component designs on the Material Design Principles and with just a few lines of code, we can easily change the colors, sizes, typography, and overall look and feel of our components.

Now that we’ve provided all base definitions needed for the igx-theme, and have configured the igx-dark-theme mixin, we need to only apply .light-theme and .dark-theme CSS classes somewhere at DOM element root level and toggle it on button click.

Result

ns6nmMPedTwr0gun8UGBjLC9fISpowsz74Ek

Wrapping up

Everything is possible with the right tooling. We have created a Portfolio Web application using the full power of the Angular Framework, Firebase Authentication services, and Cloud Database store/synchronization.

You can find the GitHub repository and the actual portfolio application here.

Feel free to share in the comments below any questions that you have, suggestions as to what can be improved or changed in the app, or any problems that you’ve encountered while configuring your Firebase account or application.