How I wanted a new JS project and partially learnt Angular2…

Harry Lincoln
7 min readJul 13, 2017

--

… but by all accounts: my love/hate relationship with Firebase 🔥

Image credit: http://onehungrymind.com/

We all go through that self-questioning at the stage of wanting to find more exciting work:

“But am I ready?”

That’s a question I’ve been asking myself since EVER when on the brink of readying to enter into the job search mentality.

It can mean many things:

1. Do I have the skills?

2. Could I prove I’ve GOT the skills in an interview?

3. Should I really just start a project of my own that’s maybe something a little out of my league so I can get an edge on the tech I really wanna learn?

… … …

This is an account of how I focussed on 3.

I wanted to learn Angular2, after having used AngularJS/1 in many a project professionally. There’s definitely a certain appeal of using something like TypeScript to bring down that syntax error rate in your IDE, and/or how it ships nicely with Angular2. Being able to hover over a particular method (with a decent Sublime plugin) to find out EXACTLY what it does, and quickly, is sooooo decent. Hell, how angular2 handles errors in general is way better than its predecessor.

Anyhoo, I’d recently been given a great opportunity to build an app using websockets at work, and getting to grips with the fundamentals of it:

  • Using it in conjunction with a RESTful API
  • Writing a decent angular service that would listen for particular things (and do particular things as a result)
  • Understanding request/response headers
  • Getting my head around things like token verification

I wanted to be able to conceptualise more and try and build a front AND backend for an app of my own.

// STEP 1 :: Proof of concept

I needed an application, in both senses:

Question 1. A rough idea of a website/app (or at least a feature)
Question 2. A rough stack outline of the tech that would be required

So I decided on:

Answer 1.
A feature that would allow users to create accounts with an email and password, sign in/out and save some stuff to their account area.

Answer 2.
Frontend: Angular2 & TypeScript
Database: Google Firebase
Backend: nodeJS & express

// STEP 2 :: Has this been done by other developers and can I nick any code (while retaining some dignity by understanding it and adapting it?)

Yes, but either 1. a while ago and not really compatible with the tech I wanted to use or 2. something a bit too granular for what I wanted. Not to say either of those examples were bad, of course…

// STEP 2.1 :: Initial research

A great starting point was getting angularFire2 integrated into my angular app — a great piece of middleware. This meant that I could read stuff that I was inputting into my firebase database directly.

But there was a serious limitation with angularFire2 v4:

I couldn’t create a user with email/password in the most recent version of angularfire — I soon realised that it was time to delve into the world of the Firebase Admin SDK.

So, a backend would have to run firebase-admin to create a user with an email address and password for me. A GREAT repo for this was Anthony Budianto’s Express Firebase.

// Step 2.2:: Sketch it out!

So I was beginning to understand what would be needed in order to do this thing…

// Step 3:: Angular2 Modules, Components and other partials that would communicate between the backend and the firebase database itself.

Before we get into it, the two repos in question you can find here:

You’ll need to run up both locally (ie. have the frontend compiling and the backend init’d). So check both README files and follow the steps. When you’re running both instances head on back here…

The first example I’d like to take ya’ll through is creating a user via the backend (express) and then signing in via the frontend (angularfire2).

The app bootstraps and authenticates with Firebase through Angularfire2. This would allow me to read the basics of what I would eventually write to the database:

Note line 26 where the AngularFireModule is included, passing in the environment variables.

Now I had my basic setup ready and awaiting the component that I would need to write in order for the actual information to be shown on the frontend:

The real meat of this snippet starts at the constructor…

Let’s start with the arguments:

  • db: AngularFireDatabase: A service that is being used here in this case to retrieve data from the /users database table.
  • afAuth: AngularFireAuth: Injectable service for managing the authentication state. So we’re saying at line 17 that if we’re authenticated, and there’s a uid on the auth propertyres , then the data stored under the user uid in the firebase /users database table is what we want to display.
  • afService: AF: Custom angularFire2 service that we’ll use to communicate with our backend later on.

afService is an imported method (line 3) we can use here in app.component.ts to hook into a partial purely dedicated to carrying out functions that relate to the express BE.

Let’s take another look at an example of that updated component (much like the last snippet, but with the addition of createNewUserHit() ):

And in the html partial below we can see how the buttons under Example 1 integrate createNewUserHit() :

CHECK: your backend is running, yeah?

Ok, sweet 😅 Let’s continue…(and don’t worry, you’ll see some backend code soon enough).

Head back to your browser, open up the dev tools and hit ‘Create user via backend’. Flick back between the network tab (XHRs) and the console.

Check 1/3:

Fig.1 :: Logged response from BE

Check 2/3: And now let’s check in the console of our backend what’s happened:

Fig.2 :: Logged response(s) on BE when FE payload hits it

Check 3/3: Aaaaaaand to complete the holy trinity; has it turned up in Firebase?

Fig.3 :: Firebase Users
Fig.3.1 :: Firebase Database: users table with uid as property

Success! But holy hell, did we send all that stuff to the database from the FE? Surely there’s some jiggery pokery going on in the BE because there’s more there than just an email address… 🤔

When firing off createNewUserHit() from the button a few things happened, and in this order:

  1. The afService was called upon in app.component.ts to send a request to the backend (line 36):

2. That request hits the express route in src/routes.js in your backend repo:

So we can see in the snippet above that on line 8 we’re accessing firebase admin’s auth and creating a user, using said method. We pass in the email address and password from the frontend request.

After that’s done via a promise we log some stuff out to our backend terminal to check things are happening, then use Firebase Admin’s reference to the users database and set some data to a table based on the uid (line 19 of snippet above).

So what about showing that data we’ve saved on the frontend?

Exactly! Head back over to your browser, (still with the console/network open), and hit the ‘sign in using email and pass’ button. The function bound to the click will access firebase through angularfire2 and show the relevant information based on the uid. So now you should see this:

Fig.4 :: Successfully signed in as the user we created, and displaying account info

So there we have it: by using this.afAuth.auth.signInWithEmailAndPassword we sign in through angularFire2, which knocks the constructor to update the data since we’re now signed in. Hooray!

Moving on to Example 2… a bit of a playground:

Because you’re still signed in after finishing up in Example 1 this means that you can get a token from the current user through angularFire2:

So basically what’s happening here is you’re asking angularFire2 to give you a token ID so when logging in to the BE, to perhaps do some further work later on, your BE needs to know you’re legit.

So this request hits http:localhost:8081/api/hello on our backend. Again, Express parses what to do when a request hits that route and we have the following function fired:

These two statements are doing a few things:

1. Handling authentication via the brilliant express-firebase-middleware on every route that’s nested under api/
2. Some cors() config was needed in order to get the frontend and backend playing nice. This can be found in index.js
3. A simple return back to the frontend telling it that the BE knows you’re good for it.

This ‘step’ was always intended just to see if the token verification had worked passed api/.

So thanks for reading ya’ll! Hope you learnt something… I certainly did! And by all means; drop me a comment if you wanna know more.. I’ll try my best to help!

--

--