Saturday, August 12, 2017

Developing Mobile Web Apps: When, Why, and How

There are 6.8 billion people on the planet, 5.1 billion of whom own a cell phone (source). And today, an ever-growing percentage of these devices are smartphones. According to a recent Pew Research Center Study, the number of users accessing the Internet on their smartphones has more than doubled in the past 5 years, as has the number of users downloading and using mobile apps. Of those who use the Internet or email on their phones, more than a third go online primarily through their handheld devices.
Indeed, mobile computing is becoming increasingly ubiquitous… and it’s awesome.
Except, of course, when it’s not.
As a mobile device user, few things are as frustrating and difficult to fat-finger-navigate as a poorly designed mobile web or native app.
And as a mobile app developer, few things can be as intensely irritating as striving to support as wide a range of mobile clients as possible, each of which has its own frustrating set of idiosyncrasies. Whether you choose to develop a mobile web, native, or hybrid app, the quest to support multiple mobile browsersmore-exotic devices, and platforms can be quite a gut wrenching experience indeed.
This web app development tutorial seeks to help you navigate different browsers and platforms.
As a mobile device user, few things are as frustrating and difficult to fat-finger-navigate as a poorly designed mobile web or native app. And as a mobile app developer, few things can be as intensely irritating as striving to support as wide a range of mobile clients as possible, each of which has its own frustrating set of idiosyncrasies.
Of course, not every developer today needs to worry about supporting mobile clients. But the increasingly omnipresent nature of mobile devices and applications strongly suggests that those who don’t need to support mobile clients today will more than likely need to do so in the not-too-distant future. So if you’re not already thinking about mobile app development, you probably should be.

Mobile app: Web vs. native vs. hybrid (help me choose!)

As is true with most technology selections, there’s no one-size-fits-all answer when it comes to the type of mobile app to develop. There are numerous web app best practices to consider, not all of which are technical. Who is your target audience? Are they more likely to prefer a mobile web or a native app? What development resources do you have and which mobile technologies are they most familiar with? What is the licensing and sales model that you’re envisioning for your product?
Generally speaking (although there are always exceptions), the mobile web route is faster and cheaper than the native app route, especially when the objective is to support a wide range of devices. Conversely, there may be capabilities native to the mobile device (such as the movement sensor and so on) that are essential to your app, but which are only accessible via a native app (which would therefore make the mobile web app choice a non-starter for you).
And beyond the web vs. native question, a hybrid app may be the right answer for you, depending on your requirements and resource constraints. Hybrid apps, like native apps, run on the device itself (as opposed to inside a browser), but are written with web technologies (HTML5, CSS and JavaScript). More specifically, hybrid apps run inside a native container, and leverage the device’s browser engine (but not the browser) to render the HTML and process the JavaScript locally. A web-to-native abstraction layer enables access to device capabilities that are not accessible in mobile web applications, such as the accelerometer, camera, and local storage.
But whatever choice you make – whether it be mobile web, native or hybrid app – be careful to adequately research and confirm your assumptions. As an example for the purposes of this mobile web app development tutorial, you may have decided to develop a native app for e-commerce to sell your products, but according to Hubspot, 73% of smartphone users say they use the mobile web more than native apps to do their shopping… so you may have bet on the wrong horse.
But whatever choice you make – whether it be mobile web, native or hybrid app – be careful to adequately research and confirm your assumptions.
And then, of course, there are the practical considerations of time and budget. As one of my favorite sayings goes, “faster, better, cheaper… pick any two”. While time-to-market and cost constraints are of paramount importance in web application development, it’s crucial not to compromise too heavily on quality in the process. It’s quite difficult to recover the confidence of a user who has had a bad first experience.
Indeed, mobile web, native, and hybrid apps are all radically different beasts, each with their own unique set of benefits and challenges. This development tutorial specifically focuses on methodologies and tools to employ, and pitfalls to avoid, in the development of highly functional, intuitive, and easy-to-use mobile web applications.
A critical best practice in determining how to develop a mobile web application is to know your customer.

Plan ahead (“if you don’t know where you’re going, you just might end up there…”)

Identifying your (or your customer’s) requirements is one of the most essential best practices in app development, mobile or otherwise. Carefully research the targeted capabilities to determine if they are achievable in a web app. It’s quite frustrating, and highly unproductive, to realize that one or more of your essential client functions aren’t supported, when you’ve already invested the time and resources to design the web-based interface and supporting infrastructure.
Another common gotcha for mobile web app developer newbies is to ass-u-me that web-based code for a desktop browser will work “as is” in a mobile browser. Not. There most definitely are differences and, if you’re not aware of them, they can definitely bite you. The HTML5 <video> tag’s autoplay functionality, for example, doesn’t work on mobile browsers. Similarly, the CSS transition and opacity properties are not supported (or at least are not consistently supported) in most mobile browsers nowadays. You will also have problems with some web API methods on a mobile platform, such as the SoundCloud music streaming API that requires Adobe Flash which is not supported on most mobile devices.
A common gotcha for mobile web app developer newbies is to ass-u-me that web-based code for a desktop browser will work “as is” in a mobile browser.
A particularly complicating factor in mobile web application development is that the lifespan of mobile devices tends to be much shorter than that of desktop displays (the average lifespan of a cell phone in the U.S. is around 21 months). These shorter device life spans, accompanied by constant releases of new mobile devices and technologies, yield an ever-changing landscape of to-be-targeted devices. While working in a browser does somewhat alleviate this issue by shielding you from a number of device-specific issues, you will still need to design a browser-based view that supports many different screen resolutions (as well as adjusting appropriately for landscape and portrait orientations).
Thought needs to be given as well to supporting Apple’s Retina Displays (liquid crystal displays that have a pixel density high enough that the human eye is unable to discern individual pixels at a typical viewing distance). Several Apple products – including the iPhone, iPod Touch, iPad, MacBook Pro, iPad Mini, and iPad Air – offer Retina displays. For a mobile web app in particular, it’s important to be aware that a Retina display makes low resolution images (which are typically served to mobile devices) look fuzzy and pixelation can occur. The best app development solution in these cases is to have the server recognize that the request is coming from a Retina device and to then provide an alternate higher resolution image to the client.
If you want to use some of the cool HTML5 stuff, remember to verify in advance that the functionality you’re looking for is supported across the device landscape that your customers are likely to be using. For example, in iOS 6 and above, there is no support for the navigator getUserMedia functionality since the camera is only accessible through native apps. Two great resources for checking what’s supported on specific devices and browsers are caniuse.com and html5test.com.
Remember to verify in advance that the functionality you’re looking for is supported across the device landscape that your customers are likely to be using.
CSS3 media queries can also help you provide customized content for each device. Here’s some example code for capturing different device characteristics, such as pixel density, screen resolution, and orientation:
/* For lower than 700px resolutions */
@media (max-width: 700px) { ... }
/* Same as last but with the device orientation on land scape */
@media (max-width: 700px) and (orientation: landscape) { ... }
/* Including width and orientation you can add a media type clause,
   in this case 'tv' */
@media tv and (min-width: 700px) and (orientation: landscape) { ... }
/* for low resolution display with background-image */
.image {
    background-image: url(/path/to/my/image.png);
    background-size: 200px 300px;
    height: 300px;
    width: 200px;
}
/* for high resolution (Retina) display with background-image */
@media only screen and (min--moz-device-pixel-ratio: 2),
only screen and (-o-min-device-pixel-ratio: 2/1),
only screen and (-webkit-min-device-pixel-ratio: 2),
only screen and (min-device-pixel-ratio: 2) {
    -repeat;
        background-size: 200px 400px;
    /* rest of your styles... */
    }
}

Performance, performance, performance

“OMG, this thing is sooooo slow!” As a mobile web app developer, those are probably the very last words you ever want to hear from one of your users. You must therefore think carefully about how to reduce and optimize each byte and server transfer to reduce the user’s wait time. It’s unrealistic to expect that transfers will always be done over a WiFi network, and you should know that 60% of mobile web users say they expect a site to load on their mobile phone in 3 seconds or less (source). Similarly, Google found that, for every extra 5 seconds of load time, traffic dropped by 20% (and it is also worth noting that search engines look at load times as part of their calculation of page quality score).
60% of mobile web users say they expect a site to load on their mobile phone in 3 seconds or less.
As a part of this web app development tutorial, here are a few tips that can help optimize the performance of your mobile web app and minimize latency:
  • Image Optimization. Image load time is well-known to be one of the biggest performance issues affecting page load on mobile devices. Use of online image optimizers, such as smushit.com, can be helpful in addressing this issue.
  • Code compression. Compressing your JavaScript and CSS files, depending on the amount of code you have, can potentially have a significant impact on performance.
  • Database queries.
    • Some mobile device browsers don’t accept as many cookies as desktop browsers do, which can result in the need to execute even more queries than usual. Server-side caching is therefore especially crucial when supporting mobile web app clients.
    • Remember to employ the appropriate filters to preclude SQL query injection that could otherwise compromise the security of your site and server.
  • Content delivery networks (CDN). If you are planning to provide lots of videos, images, audio files, or other types of media, use of a CDN is highly recommended. Some of the more common commercial CDNs include Amazon S3Microsoft Windows Azure, and MaxCDN. The advantages of using a CDN are numerous and include:
    • Improved download performance. Leveraging a CDN’s resources enables you to distribute load, save bandwidth, and boost performance. The better CDNs offer higher availability, lower network latency, and lower packet loss. Moreover, many CDNs provide a globally distributed selection of data centers, enabling downloads to occur from a server closer to the user’s location (resulting in fewer network hops and faster downloads).
    • More concurrent downloads. Browsers typically limit the number of concurrent connections to a single domain, after which additional downloads are blocked until one of the previous downloads has completed. You can often see this limit in action when downloading many large files from the same site. Each additional CDN (on a different domain) allows for additional concurrent downloads.
    • Enhanced analytics. Many commercial CDNs provide usage reports that can supplement your own website analytics and which may offer a better quantification of video views and downloads. GTmetrix, for example, has an excellent website reporting tool for monitoring and optimizing the sources loaded on your site.

Your mobile web app development toolbox

“The right tools for the right job” is an age-old adage that applies as much to software development as it does to any other domain. This tutorial provides and introduction to some of the more popular and widely-used tools for mobile web app development, but bear in mind that there may very well be other tools that are the “right” ones for developing your mobile web app, depending on your requirements and available resources.

As mobile web developers tend to face many of the same common challenges – such as cross-browser compatibility and inconsistent HTML and CSS in mobile browsers – frameworks have been developed (based on HTML5 and CSS3) that are specifically designed to address these issues and to work as flawlessly as possible on a wide array of smart phones and tablets. Most of these frameworks are lightweight, which helps facilitate fast mobile web browsing without compromising the look and feel of your site.
Broadening our view beyond the mobile landscape, if there is a single popular JavaScript framework worth mentioning, it is jQuery. If you’re familiar with the desktop version, I recommend trying jQuery Mobile for your mobile web app. It has a widget library that converts semantic markup into a gesture-friendly format, making operations easy on touch-screens. The latest version consists of a really lightweight code base that packs a punch with a lot of graphical elements that really can improve your UI.
Another alternative, Sencha Touch, is rapidly gaining market share as well. It offers excellent performance overall and helps produce a mobile web user interface that largely looks and feels like a native one. Its full-featured widget library is based on Sencha’s ExtJS JavaScript library.
Here are some key differences to consider when comparing jQuery Mobile and Sencha Touch:
  • Look and feel. Generally speaking, the look and feel of a Sencha Touch app is crisper and superior to that of a jQuery mobile app, but it is important to remember that such reactions do tend to be highly subjective.
  • Extensibility. jQuery Mobile offers lots of 3rd party extensions and is inherently designed to be highly extensible, whereas Sencha Touch is currently much more of a “closed” framework.
  • Device support. jQuery Mobile currently targets a larger cross-section of devices than Sencha Touch.
  • HTML “vs.” JavaScript. jQuery is largely HTML-centric (i.e., extending and manipulating existing HTML in JavaScript), whereas Sencha Touch coding is entirely JavaScript-based. (This is an example, incidentally, of the skill set of your development team being important to consider when making your technology selections.)
  • External dependencies. jQuery mobile requires jQuery and jQuery UI for DOM manipulation, whereas Sencha Touch has no external dependencies.
  • Learning curve. Most developers find the ramp-up time with jQuery to be less than that of Sencha Touch, perhaps fueled by the large percentage of web developers who are already familiar with the standard jQuery libraries.

Responsive Frameworks

An increasing number of responsive frameworks have begun cropping up in recent years, with two of the currently most popular being Bootstrap and Foundation. In short, responsive frameworks simplify and streamline web-based responsive UI design and implementation, encapsulating the most common layouts and UI paradigms into a reusable, performance-optimized framework. Mostly based on CSS and JavaScript, many of these frameworks are open-source, free to download, and easily customizable. Unless you have a highly peculiar set of requirements, it is likely that use of one of these frameworks will reduce the level-of-effort to design and implement your mobile web application.
Examining the two leading options, Bootstrap and Foundation, a few of the key differences to consider include:
  • Targeted platforms. While Bootstrap does support mobile, tablet, and desktop devices, it is primarily oriented toward desktop use. Foundation, on the other hand, is designed for essentially all screen sizes and types.
  • Browser compatibility. Bootstrap is compatible with IE7 or higher, whereas Foundation is only compatible with IE9 or higher.
  • Diversity of layouts and components. Bootstrap has a significantly larger collection of UI elements than is offered by Foundation.
  • Auto-resizing. With Foundation, the grid shrinks and stretches according to the current browser height and width, whereas Bootstrap only supports a pre-defined set of grid sizes based on a standard set of screen sizes.

Testing and debugging your mobile web app

Debugging mobile web apps can be tricky and somewhat frustrating, especially if you need to scrounge around for different devices to test on, or install SDKs for a (typically imperfect) emulation of the targeted client platforms.
In this context, one clear advantage of mobile web app development (as compared with native app development) is that you can utilize standard browser-based developer tools to debug your application. Based on my personal preference for remote debugging, the one I recommend in this app development tutorial is Chrome with its DevTools. Other standard options include Firefox with Firebug or Opera’s Dragonfly tools.
When learning how to develop web applications, look toward Chrome and its DevTools.
Some of the reasons I prefer Chrome with its DevTools include:
  • Mobile emulator in Chrome’s DevTools. This is perhaps alone sufficient reason to select Chrome for debugging of mobile web apps. Key features include emulation of touch events, user agent spoofing, network bandwidth throttling, geolocation overrides, device orientation overrides, and CSS Media Type Emulation.
  • Interactive editor. Ability to edit JavaScript or CSS on-the-fly.
  • Superior JavaScript debugger. Allows for DOM breakpoints and provides the ability to profile your JavaScript code execution time.
  • Built-in JSON and XML viewers. Avoids the need for any plugins to inspect server responses.
  • Support for the Android Debug Bridge (ADB) protocol directly over USB. Facilitates easy instantiation of a remote debugging session. (Here is a good tutorial by Google on how to start remotely debugging in Chrome.)
  • Dynamic inspection of resources. Allows you to inspect your app’s local data sources, including IndexedDB or Web SQL databases, local and session storage, cookies, and Application Cache resources. You can also quickly inspect your application’s visual resources, including images, fonts, and style sheets.
To test the layout and cross browsing compatibility of your web app, you can also use some helpful online tools, such as BrowserStack. Just enter the URL for your application, select the browser, version, and operating system, and you’ll get the emulated view (and load speed) of your site in that environment. Another useful tool for the this purposes is CrossBrowserTesting.

Wrap up

With the continued rapid expansion of the number, variety and sophistication of mobile devices on the market and in use today, the need for effective, user-friendly, high performance mobile applications is likely to increase substantially. Being able to develop these applications intelligently and efficiently will therefore continue to be of paramount importance.
Many factors must be considered when choosing between the web, native, and hybrid options for mobile applications. Each has its own advantages, but mobile web apps will often represent your most efficient development (and therefore time-to-market) option. Should you choose to go down that path, I hope this web app development tutorial helps get you more directly and successfully to your destination.

Friday, August 11, 2017

Building Real-Time, Multi-Platform Mobile Applications: Examples Using Ionic Framework and Firebase

One of the major problems companies encounter when making a smartphone application is a multiplicative cost of building a native application across different platforms. While savvy front-end developers have tuned into the development of several hybrid platforms that promise to help address this issue, Ionic Framework and Firebase are a dynamic duo that jointly really do give us amazing flexibility in building real-time smartphone applications using JavaScript and HTML5.
This tutorial introduces the capabilities of these multi-platform mobile development tools and even provides some Ionic and Firebase examples.
Combined, Ionic and Firebase are a great multi-platform development solution.

Introducing the Ionic Framework

The Ionic Framework consists of three main components:
  1. An SASS-based UI framework designed and optimized for mobile UIs.
  2. An AngularJS front-end JavaScript framework used to rapidly build scalable and fast applications.
  3. A compiler (Cordova or PhoneGap) for native mobile applications with CSS, HTML, and JavaScript.
The Ionic framework is also packed with lots of useful CSS components out-of-the-box.
Kudos to Ionic for providing extensive documentation, examples, and starter videos to help simplify the learning curve and get developers up and running quickly.

Introducing Firebase

Firebase is a backend-as-a-service schema-less data system that provides real time data syncing without requiring any custom code to be written. Firebase makes much of your back-end development obsolete, thereby significantly reducing multi-platform development time.
Key features and benefits include:
  1. Data changes without code changes. All data changes are published to clients immediately, without any backend code modification needed.
  2. Lots of adapters. There are adapters, with good support and documentation, for all popular JavaScript frameworks, and mobile platform SDKs. (We used AngularFire, which is the AngularJS binding for Firebase, in this article.)
  3. Ease of authentication. Authentication in Firebase is as simple as a single method call, regardless of the authentication method. Supports simple email and password, Google, Facebook, Twitter, or Github based logins.
  4. Offline enabled. All Firebase data is offline-enabled, so an application can be fully (or close to fully) functional in disconnected mode. Applications are automatically synchronized when the connection is restored.
  5. Configuration dashboard. Much of Firebase (security rules, for example) can be easily configured through Firebase’s intuitive dashboard interface.
  6. JSON-centric. In Firebase, all data is stored and retrieved in the form of JSON objects.
Firebase also offers cloud services for hosting the front-end code which can sabe significant time in deployment and maintenance.
It is also worth noting that Firebase was acquired by Google this past October which has given it significantly more attention and visibility.

A Simple Use Case Example: Expense Tracking

Roommates often share expenses and rely on one another in times of need. So, let’s help roommates track their expenses, and help them reconcile at the end of the month.
To make things even more interesting, let’s build a multi-platform mobile application that will provide real-time updates, so they can each monitor expenses as they occur.
This Ionic and Firebase example demonstrates smooth multi-platform app development.
Now that we’ve decided what we want to build and we’ve been introduced to the tools, let’s get started!

Getting Started with Ionic and Firebase

The first thing we need to do is install Ionic. Follow the installation instructions provided on the Ionic Getting Started page. (Note that Ionic has a dependency on NodeJS, so the instructions will require you to install that as well if you don’t already have it on your machine).
The AngularFire 5 minute tutorial is a great place to begin getting familiar with Firebase. And if you’re a “tinkerer” or a tactile learner like me you may want to pull my implementation from GitHub and start playing with the code.

Coding Our Multi-Platform App

For this tutorial, we’re going to use the sample tabs app provided as part of the Ionic installation as the basis for our app. (You can run the sample app with the command ionic start myApp tabs.)
Open the sample tabs app in your favorite IDE (I’m using Webstorm) and let’s start modifying it to build our roommates app.
For our example Ionic and Firebase app, we’ll need the following three screens:
Before creating these screens, let’s remove the “Friends detail screen” provided by default with the sample app as follows:
  1. Delete the www/templates/friend-detail.html file.
  2. In www/js/app.js, remove (or comment out) the state for friend-detail.html.
  3. In www/js/controllers.js, remove the FriendDetailCtrl controller that is referenced in the state we deleted.
Now let’s change the icons and the text of the tab selectors at the bottom of our screen to be the following:
Change the icons and tab text using this example code for Ionic framework.
This is simply done by making the following changes in www/templates/tabs.html:
<ion-tabs class="tabs-icon-top"><!-- My Tab -->
  <ion-tab title="My Expense" icon="icon ion-log-in" href="#/tab/dash"><ion-nav-view name="tab-dash"></ion-nav-view></ion-tab><!-- Friends Tab -->
  <ion-tab title="Roomie's" icon="icon ion-log-out" href="#/tab/friends">
    <ion-nav-view name="tab-friends"></ion-nav-view></ion-tab><!-- Account -->
  <ion-tab title="Account" icon="icon ion-ios7-gear" href="#/tab/account"><ion-nav-view name="tab-account"></ion-nav-view></ion-tab></ion-tabs>
Before we hook up our data to the Firebase, let’s create a list and bind it to an array called expenses by adding the following code to www/templates/tab-dash.html:
<ion-view title="My Expenses">  
  <ion-content>
    <ion-list>               
      <ion-item ng-repeat="expense in expenses|filter:user.password.email"
                type="item-text-wrap">
{{expense.label}}
        <span class="badge badge-balanced">{{expense.cost}}</span>
      </ion-item>             
    </ion-list>            
    <div class="card assertive">                   
      <div class="item item-text-wrap">
        Total Spent <span class="badge badge-positive">{{getTotal()}}</span>
      </div>               
    </div>        
  </ion-content>     
  <ion-footer-bar>
    <input ng-model='label' type='text' id='labelInput'
           placeholder='Type a new expense...' />
    <input ng-model='cost' type="number" id="costInput" placeholder='$' />
    <button class="button icon-left ion-plus" ng-click="addExpense($event)">Add</button>
  </ion-footer-bar>   
</ion-view>
We’ll also need to extend the DashCtrl in www/js/controllers.js to include the expenses array, as well as an addExpense method and a getTotal method, as follows:
.controller('DashCtrl', function($scope) {
    $scope.expenses = [{
        by: ‘email’,
        label: ’test’,
        cost: 10
    }];
    $scope.addExpense = function(e) {
        $scope.expenses.push({
            by: < some email > label: $scope.label,
            cost: $scope.cost
        });
        $scope.label = "";
        $scope.cost = 0;
    };
    $scope.getTotal = function() {
        var rtnTotal = 0;
        for (var i = 0; i < $scope.expenses.length; i++) {
            rtnTotal += $scope.expenses[i].cost;
        }
        return rtnTotal;
    };
})
The expenses array is what stores the items in the expense list, the addExpense() method adds a new value to the expenses array, and the getTotal() method gives us the total of all items in the array.
A similar set of changes now needs to be made to tab-friends.html. Try doing this on your own, but if you run into problems, or want to verify that you’ve done this properly, you can refer to my implementation on GitHub.

Hooking in Firebase

You will need a Firebase account. You can signup here for a free Firebase “Hacker Plan”.
One you sign up, you will receive your root url, which will look something like https://<yourfirebase>.firebaseio.com.
Enabling Firebase in our app requires two small mods to our app.
First, we need to include the Firebase scripts in the app’swww/index.html file as follows:
<script src='https://cdn.firebase.com/js/client/1.1.1/firebase.js'></script>
<script src='https://cdn.firebase.com/libs/angularfire/0.8.0/angularfire.min.js'></script>
<script src="js/app.js"></script>
Next, we need to add the Firebase module to our application by adding 'firebase' to the list in our AngularJS 'starter' module:
angular.module('starter', ['ionic', 'starter.controllers', 'starter.services', 'firebase'])
Firebase is now enabled, just like any other AngularJS module.
The AngularFire 5 minute tutorial will teach you to create data references in controllers. For our demo app, though, I decided to keep these references in a separate service (since this makes it much easier to maintain and update if the root url is changed). To create this service, add the following to www/js/services.js:
.factory('fireBaseData', function($firebase) {
    var ref = new Firebase("https://luminous-fire-3429.firebaseio.com/"),
        refExpenses = new Firebase("https://luminous-fire-3429.firebaseio.com/expenses"),
        refRoomMates = new Firebase("https://luminous-fire-3429.firebaseio.com/room-mates");
    return {
        ref: function() {
            return ref;
        },
        refExpenses: function() {
            return refExpenses;
        },
        refRoomMates: function() {
            return refRoomMates;
        }
    }
});
The above code adds three reference urls. One for the root and two for collections that we have named expenses and room-mates.
Adding a new collection to Firebase is simply done by adding its name to the end of your root url. So to create the expenses collection that we’ll need, all we need is the following:
https://<yourfirebase>.firebaseio.com/expenses
This will create the expenses collection, and we can then start adding objects to it.
OK, now we can hook in the expenses collection from Firebase to replace the “dummy” expenses array we created earlier. This is done by modifying DashCtrl in www/js/controllers.js as follows:
.controller('DashCtrl', function($scope, fireBaseData, $firebase) {
    $scope.expenses = $firebase(fireBaseData.refExpenses()).$asArray();
    $scope.addExpense = function(e) {
        $scope.expenses.$add({
            by: < someemail > ,
            label: $scope.label,
            cost: $scope.cost
        });
        $scope.label = "";
        $scope.cost = 0;
    };

    $scope.getTotal = function() {
        var rtnTotal = 0;
        for (var i = 0; i < $scope.expenses.length; i++) {
            rtnTotal += $scope.expenses[i].cost;
        }
        return rtnTotal;
    };
})
A similar set of changes needs to be made to FriendsCtrl. I again recommend that you try doing this on your own, but if you run into problems, or want to verify that you’ve done this properly, you can refer to my implementation on GitHub.
To verify that it’s working, while running the app on two different clients, add a new expense, and see that it shows up in the list on both clients. If it works… woo-hoo! You’ve now successfully hooked up your Ionic app with Firebase!
You can test your multi-platform app on different devices by connecting a device to your system and running ionic run android or ionic emulate ios. Refer to the Ionic documentation for more information on testing your app.

Account Management and Security with Firebase

Although the basic functionality is now working, one serious issue is that our app is currently completely insecure. The entire world can see your expenses, without any permissions or logins being required. This obviously needs to be addressed.
Firebase provides a powerful yet simple authentication framework using “rules”. There is a lot that can be done using Firebase’s Rules Language. (Refer to the Firebase security documentation for more detail.)
In our case, we will write a very simple rule to block unauthorized users from accessing our data. To do this, open your root url, click on “Security & Rules” in your left action bar, paste the code below in your rules, and click Save.
{
    "rules": {
        ".read": "auth != null",
        ".write": "auth != null"
    }
}
If you run your application now you will notice that there is no data. You can even try to inspect your request by using browser tools and you should see a message in your console stating that you are not authorized to view the data.

Creating User Accounts and Enabling Login

You can authenticate your users by letting them create their own email/password combination, or use any of their existing Google, Facebook, Twitter, or Github login credentials. For email/password authentication, Firebase offers full set of API methods for password change, reset, etc. More information about authentication using Firebase can be found in the Firebase guide.
For our demo app, we will create two user accounts via the Firebase interface. This can be done by going to your Firebase root url and doing the following:
  1. Click the Login & Auth on the left side action bar.
  2. Select the checkbox to Enable Email & Password Authentication.
  3. Scroll down to find the “Add New Accounts Form”
  4. Add your accounts using “Add New User”.
Enabling secure logins is essential when developing multi-platform applications with Ionic and Firebase.
To enable the login interface for your users, first add the following code to www/templates/tab-account.html:
<ion-view title="Account">
  <ion-content>           
    <div class="list" ng-show="showLoginForm">
      <label class="item item-input">
        <span class="input-label">Email</span><input type="text" ng-model="em"/>
      </label>
      <label class="item item-input">
        <span class="input-label">Password</span><input type="password" ng-model="pwd"/>
      </label>
      <button class="button button-block button-positive" ng-click="login(em, pwd)">Login</button>
    </div>            
    <div class="card" ng-hide="showLoginForm">      
      <div class="item item-text-wrap">You are logged in as {{user.password.email}}</div>                
    </div>
    <button class="button button-stable" ng-click="logout()" ng-hide="showLoginForm">Logout</button>
  </ion-content>  
</ion-view>
Then add the following to AccountCtrl in www/controller.js:
.controller('AccountCtrl', function($scope, fireBaseData) {
    $scope.showLoginForm = false; //Checking if user is logged in
    $scope.user = fireBaseData.ref().getAuth();
    if (!$scope.user) {
        $scope.showLoginForm = true;
    }
    //Login method
    $scope.login = function (em, pwd) {
        fireBaseData.ref().authWithPassword({
            email    : em,
            password : pwd
        },function(error, authData) {
            if (error === null) {
                console.log("User ID: " + authData.uid +
                            ", Provider: " + authData.provider);
                $scope.user = fireBaseData.ref().getAuth();
                $scope.showLoginForm = false;
                $scope.$apply();
            } else {
                console.log("Error authenticating user:", error);
            }
        });
    };

    // Logout method
    $scope.logout = function () {
        fireBaseData.ref().unauth();
        $scope.showLoginForm = true;
    };
});
One important thing to be aware of from a security standpoint is that Firebase logins are persistent by default. Therefore, if you want your user to need to login each time the application is started, you will need to modify the Firebase configuration accordingly. To do this, just one time after a successful login, execute the following code:
var r = $firebase(fireBaseData.refRoomMates()).$asArray();
// NOTE: Substitute the email addresses of your two user accounts in the line below
r.$add(["user1@mail.com","user2@mail.com"]);
You can add this in the account controller after successful login, or put a break point after successful login and run it in your console inspector.

Filtering Based on User

The multi-platform mobile app is still missing one important feature though. We want to distinguish your expenses from those of your roommate. Now that we have created two accounts, we just need to filter the data on our views.
We first need to modify the dashCtrl in www/js/controllers.js in order to (a) get the data for the current user into $scope and (b) save any added expenses for the current user:
.controller('DashCtrl', function($scope, fireBaseData, $firebase) {
    $scope.expenses = $firebase(fireBaseData.refExpenses()).$asArray();
    $scope.user = fireBaseData.ref().getAuth();
    // ADD MESSAGE METHOD
    $scope.addExpense = function(e) {
        $scope.expenses.$add({
            by: $scope.user.password.email,
            label: $scope.label,
            cost: $scope.cost
        });
        $scope.label = "";
        $scope.cost = 0;
    };
    $scope.getTotal = function () {
        var rtnTotal = 0;
        for (var i = 0; i < $scope.expenses.length; i++) {
            rtnTotal += $scope.expenses[i].cost;
        }
        return rtnTotal;
    };
})
Next we need to add a filter in www/templates/tab-dash.html to show only the current user’s expenses:
<ion-item ng-repeat="expense in expenses|filter:user.password.email" type="item-text-wrap">
OK, the Home screen is now perfect. A user can only see and add his or her own expenses.
The last and final step is to enable sharing the complete expense list between roommates. To do so, change the www/templates/tab-friends.html to add this filter:
<ion-item ng-repeat="expense in expenses|filter:roomiesEmail" type="item-text-wrap">
Then modify FriendsCtrl in www/controllers.js as follows:
.controller('FriendsCtrl', function($scope, fireBaseData, $firebase) {
    $scope.user = fireBaseData.ref().getAuth();
    $scope.expenses = $firebase(fireBaseData.refExpenses()).$asArray();
    $scope.roomies = $firebase(fireBaseData.refRoomMates()).$asArray();
    $scope.roomies.$loaded().then(function(array) {
        //array = [[set1_rm1_email, set1_rm2_email], [set2_rm1_email, set2_rm2_email] ...]
        for (var i = 0; i < array.length; i++) {
            if (array[i][0] === $scope.user.password.email) {
                $scope.roomiesEmail = array[i][1];
            } else if (array[i][1] === $scope.user.password.email) {
                $scope.roomiesEmail = array[i][0];
            }
        }
        $scope.$apply();
        // NOTE: For simplicity, this demo only supports the 2-roommate use case
    });
    $scope.addExpense = function(e) {
        $scope.expenses.$add({
            by: $scope.roomiesEmail,
            label: $scope.label,
            cost: $scope.cost
        });
        $scope.label = "";
        $scope.cost = 0;
    };
    $scope.getTotal = function () {
        var rtnTotal = 0;
        for (var i = 0; i < $scope.expenses.length; i++) {
            rtnTotal += $scope.expenses[i].cost;
        }
        return rtnTotal;
    };
})
That’s it! Install/update the app on both your device and your roommate’s device and you should be all set!

Wrap Up

Our simple example only begins to scratch the surface of what can be accomplished – and how easily it can be accomplished – using Ionic and Firebase. They truly are a powerful duo for building real-time, multi-platform smartphone applications using JavaScript and HTML5.