Firebase Logo

Email and Facebook Authentication with Ionic 1.x and Firebase



·

Firebase has been on my radar lately as they seem to be doing a lot with Ionic. I’ve seen a few blog posts and a few people mentioning that they built their app with it. I’ve been looking at Parse recently but decided to give Firebase a go to see which I liked better.

In this tutorial we will look at adapting the Parse login system tutorial I created earlier to work with Firebase instead. We will set up a simple email and Facebook authentication process, and we will also look at how to integrate the Facebook Connect plugin so that users can authenticate using the Facebook app on their native device, rather than using an in app browser.

Parse vs Firebase

I’ve previously written some tutorials on using Parse in an Ionic application to handle user authentication. Firebase is very similar to Parse, so what’s the difference? Why should you use one over the other?

I haven’t spent enough time with either service to make any kind of significant comparison (if you have, please leave a comment below with your thoughts) but at a glance these seem to be the main differences:

  • It’s hard to make a direct comparison, but Firebase seems a little cheaper
  • Firebase does not have push notifications included (I imagine Firebase + Ionic Push will be a common combination in future)
  • Firebase is better for live data like multiplayer games or chat applications
  • Parse is better for more complex data
  • Firebase seems to be more tightly integrated with Ionic

I’m sure there’s a bunch more differences out there, but the two services more or less do the same thing so it’s probably just going to come down to preference or nitty gritty requirements of an application. I certainly don’t favour one over the other (not yet at least).

Background

As I mentioned, we will be adapting this application to use Firebase instead of Parse. Apart from that though we are going to keep everything exactly the same.

I’m not going to go through how to set up the same structure again, so just follow through with the Parse tutorial first and then do this tutorial (don’t worry about setting up a Parse account or anything if you don’t intend on using it). The app will remain mostly the same, we will just be swapping out the bits where we authenticate with Parse

Setting up Firebase in Ionic

Ok, at this point I’ll assume you have an Ionic application created that is based on the Parse Authenticaiton Tutorial.

Firebase has a guide on how to get set up so if you want a more indepth walkthrough check that out – I’ll just quickly run through what you need to do in your existing Ionic application.

Add the following libraries to your index.html before you include the app.js file:

<!-- Firebase -->
<script src="https://cdn.firebase.com/js/client/2.2.4/firebase.js"></script>
<!-- AngularFire -->
<script src="https://cdn.firebase.com/libs/angularfire/1.1.2/angularfire.min.js"></script>

Add firebase as a dependency to your applications module:

angular.module('starter', ['ionic', 'firebase', 'ngCordova'])

…and that’s it. Easy peasy.

Sign up for a Firebase Account

Of course, if you want to use Firebase you’ll also have to sign up for an account. Simply head to the Firebase website and hit Sign Up. Once you’ve gone through the motions you should see your first Firebase app set up in your Dashboard:

Screenshot 2015-08-13 23.53.03

You will need to set up user authentication in Firebase before you can use it in your application, so first you will need to click on your Firebase app to open it up in your dashboard:

Firebase Dashboard

Once in there click on Login & Auth. In the Email & Password section make sure you check the following box:

Firebase Email

and in the Facebook section make sure you tick the same box and also supply your Facebook Apps ID and Secret:

Firebase Facebook

If you followed along with the Parse tutorial you should already have a Facebook App set up that you can use. If not, head back to the tutorial and set that up. When using Firebase, there’s a little bit extra you need to set up in your Facebook app, so make sure you follow these instructions from Firebase as well:

In your Facebook app configuration, click on the Settings tab on the left-hand navigation menu. Then go to the Advanced tab at the top and scroll down to the Security section. At the bottom of that section, add https://auth.firebase.com/v2//auth/facebook/callback to your Valid OAuth redirect URIs and click Save Changes at the bottom of the page. – Firebase

User Authentication

Now we’re going to replace the parts of the code that interface with Parse so that it uses Firebase instead.

Email Signup

In Parse, we sign up a user with an email address and password (and a username as well) like this:

  $scope.signupEmail = function(){

    //Create a new user on Parse
    var user = new Parse.User();
    user.set("username", $scope.data.username);
    user.set("password", $scope.data.password);
    user.set("email", $scope.data.email);

    // other fields can be set just like with Parse.Object
    user.set("somethingelse", "like this!");

    user.signUp(null, {
      success: function(user) {
        // Hooray! Let them use the app now.
        alert("success!");
      },
      error: function(user, error) {
        // Show the error message somewhere and let the user try again.
        alert("Error: " + error.code + " " + error.message);
      }
    });    

  };

Instead, we are going to replace that with this code for Firebase:

  $scope.signupEmail = function(){  

    var ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com");

    ref.createUser({
      email    : $scope.data.email,
      password : $scope.data.password
    }, function(error, userData) {
      if (error) {
        console.log("Error creating user:", error);
      } else {
        console.log("Successfully created user account with uid:", userData.uid);
      }
    });

  };

It’s pretty much the same idea really. The userData object you get in the success callback contains all of that users information (such as their email address, gravatar etc). You will need to store this userData object somewhere if you plan on using it later.

Email Login

If users can sign up with an email address then we probably want to let them sign in with their account as well. In Parase we handled email logins like this:

  $scope.loginEmail = function(){
    Parse.User.logIn($scope.data.username, $scope.data.password, {
      success: function(user) {
        // Do stuff after successful login.
        console.log(user);
        alert("success!");
      },
      error: function(user, error) {
        // The login failed. Check error to see why.
        alert("error!");
      }
    });
  };

But with Firebase we will do this:

  $scope.loginEmail = function(){

    var ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com");

    ref.authWithPassword({
      email    : $scope.data.email,
      password : $scope.data.password
    }, function(error, authData) {
      if (error) {
        console.log("Login Failed!", error);
      } else {
        console.log("Authenticated successfully with payload:", authData);
      }
    });

  };

Again, basically the same idea. The syntax is a little different but the concept is the same.

Facebook

Just like we did with the Parse application, we are going to make Facebook work both through the browser and when installed natively on a device. For this to work you need to make sure you have the Facebook Connect plugin installed as per the instructions in this tutorial (the Facebook Connect plugin isn’t quite as straight forward to set up as other plugins).

In the Parse tutorial, instead of using Parse’s Facebook login flow (which does not use the native app on the device if available) we used the Facebook Connect plugin. The benefit of the Facebook Connect plugin is that it switches the user into the Facebook app installed on their device and allows them to log in just by giving your app the ‘OK’, without using this plugin users would have to enter in their account credentials for Facebook in a pop up browser window. The Facebook Connect plugin grabs the users authentication data from Facebook and then we can pass that into the Parse or Firebase login flow (after modifying it into the formats that they like).

With the Parse example we had to modify the data we got back from the Facebook Connect plugin a bit and we will do a similar thing with Firebase, except with Firebase we just have to pass in the access token.

In the Parse tutorial, this is how we authenticated with Facebook:

  $scope.loginFacebook = function(){

    $cordovaFacebook.login(["public_profile", "email"]).then(function(success){

      console.log(success);

      //Need to convert expiresIn format from FB to date
      var expiration_date = new Date();
      expiration_date.setSeconds(expiration_date.getSeconds() + success.authResponse.expiresIn);
      expiration_date = expiration_date.toISOString();

      var facebookAuthData = {
        "id": success.authResponse.userID,
        "access_token": success.authResponse.accessToken,
        "expiration_date": expiration_date
      };

      Parse.FacebookUtils.logIn(facebookAuthData, {
        success: function(user) {
          console.log(user);
          if (!user.existed()) {
            alert("User signed up and logged in through Facebook!");
          } else {
            alert("User logged in through Facebook!");
          }
        },
        error: function(user, error) {
          alert("User cancelled the Facebook login or did not fully authorize.");
        }
      });

    }, function(error){
      console.log(error);
    });

  };

But with Firebase we will do this instead:

  $scope.loginFacebook = function(){

    var ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com");


    if(ionic.Platform.isWebView()){

      $cordovaFacebook.login(["public_profile", "email"]).then(function(success){

        console.log(success);

        ref.authWithOAuthToken("facebook", success.authResponse.accessToken, function(error, authData) {
          if (error) {
            console.log('Firebase login failed!', error);
          } else {
            console.log('Authenticated successfully with payload:', authData);
          }
        });

      }, function(error){
        console.log(error);
      });        

    }
    else {

      ref.authWithOAuthPopup("facebook", function(error, authData) {
        if (error) {
          console.log("Login Failed!", error);
        } else {
          console.log("Authenticated successfully with payload:", authData);
        }
      });

    }

  };
BONUS CONTENT: Download the source code for this tutorial by entering your email address below:

And that’s all there is to it, you should now have a functioning authentication system in Firebase with email and Facebook log in.

Summary

As you can probably tell from this tutorial, there isn’t really a whole lot of difference between Parse and Firebase at this stage. A simple log in flow, although certainly useful, is a little boring. I’ll be releasing some more Firebase and / or Parse tutorials in the future, the first of which will be a tutorial on creating a real time chat application.

What to watch next...