Firebase is a great technology that allows us to create web apps without any server-side programming, so that development becomes quicker and easier. In this article I will show you how to use it along with AngularJS to achieve the best developer and user experience possible.
What's so great about using Firebase with AngularJS? Well, if you look at how both of the technologies are made, there's your answer. Bidirectional data binding from AngularJS works exceptionally well with Firebase's "Don't just save data. Sync it." philosophy.
Development is quick, and the user experience is great—they just type something and it's already saved and available to the other connected users.
Step 1: Setting Up the Database
Let's start by creating a database. If you don't have an account yet, create one (you can sign in with GitHub!). Then log in and create an app by filling in the form and clicking the button.
Since we will be using a Facebook login further down the road, you will have to provide your Facebook app's details (that is, the app ID and the app secret) in your database's options. Click on the "Manage" button under your Firebase app name and go to the "Simple Login" tab, then enter the requested information and check "Enabled".
You will also have to configure your Facebook app to make it work. The whole process is pretty quick and is described on the Firebase website.
Step 2: Setting Up an Angular App
Let's start by creating a base HTML and JavaScript for our app. We will be creating a simple chat application that will allow users to log in using Facebook.
Create an HTML file and put this markup inside:
<html> <head> <script src="https://cdn.firebase.com/js/client/2.0.4/firebase.js"></script> <script src="https://code.angularjs.org/1.3.8/angular.js"></script> <script src="https://cdn.firebase.com/libs/angularfire/0.9.0/angularfire.min.js"></script> <script src="angular.app.js"></script> </head> <body ng-app="simpleChat"> <div ng-controller="MessagesCtrl"> <button ng-click="login()" ng-hide="authData">Log In</button> <input ng-model="newMessage.text" ng-keyup="handleKeyup($event)"> <div ng-repeat="message in data.messages"> <b>{{ message.author }}:</b> {{ message.text }} </div> </div> </body> </html>
As you can see, it contains a few scripts that we need. Of course it includes firebase.js
and angular.js
, and we also need firebase-simple-login.js
for the Facebook authentication. angularfire.min.js
contains the AngularFire module, which greatly simplifies working with Firebase.
Now create the angular.app.js
file, in which we will put our application logic. Let's start by declaring the main module, simpleChat
:
var app = angular.module('simpleChat', ['firebase']);
As you can see, the only dependency is the firebase
module from AngularFire.
Step 3: Simple Login
Now let's create the code that will allow users to log in with Facebook. Since our app is so small, we will only have one controller in there: MessagesCtrl
.
app.controller('MessagesCtrl', ["$scope", "$firebase", function ($scope, $firebase) {
The $firebase
function will allow us to connect to the Firebase database, and $firebaseSimpleLogin
will manage the login stuff.
We will need a Firebase
instance, so let's create it:
var ref = new Firebase("https://tutssampleapp.firebaseio.com/");
Of course replace 'your-unique-url'
with your database's URL. Now prepare the login object using $firebaseSimpleLogin
and the ref
we just created:
$scope.login = function(){ ref.authWithOAuthPopup("facebook", function(error, authData) { }); }
And that's pretty much it for getting the login status. If the user is logged in, the $scope.loginObj.user
variable will contain an object with the user's data; otherwise, it will be null
.
Now add a <div>
with our controller and a button to let the user sign in to the body of your page:
<div ng-controller="MessagesCtrl"> <button ng-click="login()" ng-hide="authData">Log In</button> <input ng-model="newMessage.text" ng-keyup="handleKeyup($event)"> <div ng-repeat="message in data.messages"> <b>{{ message.author }}:</b> {{ message.text }} </div> </div>
We used the ngHide
directive to hide the button when the user is logged in. Now the $scope.login()
method will just call a method with the same name on the $scope.loginObj
:
$scope.login = function(){ ref.authWithOAuthPopup("facebook", function(error, authData) { }); }
The only parameter we used is the name of the provider used to log the user in. You can test your app now, and the login button should disappear when you log in.
Step 4: Displaying the Messages
As you may expect, this will also be pretty easy. First let's prepare the HTML. We will use ngRepeat
to loop through all messages and display them:
<div ng-repeat="message in data.messages"> <b>{{ message.author }}:</b> {{ message.text }} </div>
Now we have to update the controller. Create the obj
variable that will hold the object returned from Firebase:
var obj = $firebase(ref).$asObject();
The $asObject()
method converts the whole reference to a Javascript object with a few useful methods. The one we will use is called .$bindTo()
and will allow us to create a three-way binding (Firebase-AngularJS-DOM):
obj.$bindTo($scope, "data");
We put $scope
as the first parameter, and a property's name as the second. The object we are binding will appear in $scope
under this name (as $scope.data
in this example).
And that is all you need to display the messages! Of course, unless you've put something in the messages
array in your database, you will not see anything if you run your app now.
Step 5: Sending Messages
This one will be even quicker. Let's add an input to our controller's div
, so that our users can type in messages:
<input ng-model="newMessage.text" ng-keyup="handleKeyup($event)">
The input's value will be bound to the $scope.newMessage.text
variable, and its keyup
event will fire the $scope.handleKeyup()
callback. Note that we passed $event
as the parameter, since we need to check if the user pressed Enter.
Let's define the $scope.handleKeyup()
function:
$scope.handleKeyup = function handleKeyup(e) {
First, we check if the Enter key was pressed:
if (e.keyCode == 13) {
If so, we add the user's display name to the $scope.newMessage
object, update the $scope.data.messages
array, and reset the $scope.newMessage
object:
$scope.newMessage.author = ref.getAuth().facebook.displayName; ref.child("messages").push($scope.newMessage); $scope.newMessage = {};
You also have to initialize the $scope.newMessage
object:
$scope.newMessage = {};
That's it - ppen your app in two browsers (so that you can use two Facebook accounts) and try it out! As usual, please leave any questions, comments, and general feedback in the form below.
Comments