Get the Newsletter

Aurelia Authentication Using Firebase

Posted by AureliaEffect on November 23, 2016

As a recovering full-stack developer who went the specialised front-end route a few years ago, the one aspect I have always hated about building any feature-rich web application is authentication. Thankfully a lot of convenient options have popped up over the last couple of years like Auth0 .

In this post, we are going to be using Firebase's fantastic authentication functionality in an Aurelia CLI application.

Pre-configure Firebase.

Firstly, create a new Firebase project via the Firebase developer console .

Now let's enable authentication. On the left-hand side in the project pane, you'll see "Authentication" click that and then at the top, choose the "Sign-in method" tab where you'll see a list of providers. For the sake of this article, let's just enable Google because we don't need to provide tokens or application ID's like we do for other providers such as Facebook or Twitter.

The sample application in the Github repository provided (at the end of this post) has the other providers wired up, but you'll need to get app credentials and then enable these providers yourself. Once you've done that, click on the name of your app in the left-hand pane at the top. I called my app "Aurelia Auth App."

Then you'll see three icons; Add Firebase to your iOS app, Add Firebase to your Android app and Add Firebase to your web app. Choose the last one, "Add Firebase to your web app", and you'll see a popup which contains the SDK script and some configuration details.

Mine looked similar to the following:

    
    <script src="https://www.gstatic.com/firebasejs/3.6.1/firebase.js"></script>
    <script>
      // Initialize Firebase
      var config = {
        apiKey: "AIzaSyD450934850934805934095834095",
        authDomain: "aurelia-auth-app.firebaseapp.com",
        databaseURL: "https://aurelia-auth-app.firebaseio.com",
        storageBucket: "aurelia-auth-app.appspot.com",
        messagingSenderId: "567567"
      };
      firebase.initializeApp(config);
    </script>
  
  
  

Don't use my snippet, make sure you get your own, or this tutorial might not work properly for you. Hold onto it; we'll need it soon.

Generating an Aurelia app.

Using Aurelia CLI, we are going to scaffold a new Aurelia application.

Make sure you have Node.js installed and then open up a terminal window and install the CLI as a global dependency:

    
    npm install aurelia-cli -g
  
  
  

Once this completes, test the CLI installed correctly by typing: au -v and a version number should be displayed.

Now, let's create our project. We'll call it "aurelia-secured" for the sake of this article, but you can call it whatever you want.

    
    au new aurelia-secured
  
  
  

Go through the prompts and choose whatever works for you. I favour using TypeScript, so I selected TypeScript over Babel. Keep in mind code snippets you might encounter in this post are TypeScript, but can be quickly changed to be plain old Javascript.

During the prompts, make sure you choose to install the dependencies as well. This will just run npm install, but it is one less step to worry about if you do it during the CLI process.

Coding our app.

Firstly, in the newly created application folder, open up index.html and above the script which imports scripts/vendor-bundle.js paste in your provided SDK code from Firebase. We do this to ensure Firebase's SDK loads before Aurelia code.

Your index.html file should resemble closely to the following:

    
    <body aurelia-app="main">
        <script src="https://www.gstatic.com/firebasejs/3.6.1/firebase.js"></script>
        <script>
          // Initialize Firebase
          var config = {
            apiKey: "AIzaSyD450934850934805934095834095",
            authDomain: "aurelia-auth-app.firebaseapp.com",
            databaseURL: "https://aurelia-auth-app.firebaseio.com",
            storageBucket: "aurelia-auth-app.appspot.com",
            messagingSenderId: "567567"
          };
          firebase.initializeApp(config);
        </script>
        <script src="scripts/vendor-bundle.js" data-main="aurelia-bootstrapper"></script>
    </body>
  
  
  

Congratulations, you just added Firebase into your app. If you're wondering why we are not using third party plugins like Aurelia Firebase, it is because I think Firebase already provides an excellent SDK that does not need to be over-complicated or abstracted.

If you want to use a third-party plugin, nothing is stopping you. However, this article will be focusing on the official SDK only.

If you thought that was easy, now we're going to add in authentication, which isn't any harder. Rather than make you write code step-by-step, line-by-line, just copy/paste the following well-documented code into src/app.ts:

    
    // For TypeScript, because Firebase is a global variable
    declare var firebase;
    
    export class App {
        constructor(
            private userLoggedIn = false,
            private authToken = null,
            private user = null
        ) {
            // This mostly gets called on subsequent page loads to determine
            // what the current status of the user is with "user" being an object
            // return by Firebase with credentials and other info inside of it
            firebase.auth().onAuthStateChanged(user => {
                this.userLoggedIn = user ? true : false;
                this.user = user;
            });
        }
    
        login(type) {
            let provider;
    
            // Determine which provider to use depending on provided type
            // which is passed through from app.html
            if (type === 'google') {
                provider = new firebase.auth.GoogleAuthProvider();
            } else if (type === 'facebook') {
                provider = new firebase.auth.FacebookAuthProvider();
            } else if (type === 'twitter') {
                provider = new firebase.auth.TwitterAuthProvider();
            }
            
            // Call the Firebase signin method for our provider
            // then take the successful or failed result and deal with
            // it accordingly.
            firebase.auth().signInWithPopup(provider).then((result: any) => {
                // The token for this session
                this.authToken = result.credential.accessToken;
    
                // The user object containing information about the current user
                this.user = result.user;
    
                // Set a class variable to true to state we are logged in
                this.userLoggedIn = true;
            }).catch(error => {
                let errorCode = error.code;
                let errorMessage = error.message;
                let email = error.email;
                let credential = error.credential;
            });
        }
    
        logout() {
            // Self-explanatory signout code
            firebase.auth().signOut().then(() => {
                this.userLoggedIn = false;
            }).catch(error => {
                throw new Error(error);
            });
        }
    }
  
  
  

If you would like to know how you can configure the scope to request additional information from a provider or other configuration options, the Firebase documentation has you covered here .

Lastly, add the following into app.html:

    
    <template>
        <a href="javascript:void(0);" click.delegate="login('google')" if.bind="!userLoggedIn">Login via Google</a>
        <a href="javascript:void(0);" click.delegate="login('twiter')" if.bind="!userLoggedIn">Login via Twitter</a>
        <a href="javascript:void(0);" click.delegate="login('facebook')" if.bind="!userLoggedIn">Login via Facebook</a>
        <a href="javascript:void(0);" click.delegate="logout()" if.bind="userLoggedIn">Logout</a>
    
        <div class="profile" if.bind="userLoggedIn && user">
            <h1>${user.displayName}</h1>
            <h2>${user.email}</h2>
            <img src.bind="user.photoURL" if.bind="user.photoURL">
        </div>
    </template>
  
  
  

We are only showing login links if we are not already logged in using Aurelia's if.bind which conditionally adds and removes the element from the DOM. We could also use show.bind to achieve the same thing, but the element does not get removed.

Lastly, we have a profile DIV which only gets shown if we are logged in, and we have a user object. Then inside we display some values.

Conclusion

Firebase is great. Aurelia's CLI is fantastic and combining the two allows you to create a fully-fledged client-side application with almost no work. If you would like the source code for the above example, you can find it on Github here .