Firebase Logo

Implementing the Master Detail Pattern in Ionic 1.x with Firebase



·

Andrew McGivery recently wrote a tutorial on what the “Master Detail” pattern is and how to implement it in an Ionic application. You should definitely go read his post before continuing with this one, but essentially this pattern is where you have a list of things and then you can bring up more details on a specific thing.

For example you might have a list of episodes of Game of Thrones, and you could allow users to click on a specific episode to bring up more information about that specific episode like the cast involved, trivia, and how many characters died in that episode. You don’t want to overload the user with information they don’t need to see, which is why this pattern is so commonly used.

What I’m going to do in this tutorial is modify the application Andrew created to use Firebase as the backend for data storage. This will give you an example of how to set up something like this up on a “live” backend, and also give you a bit of an intro to how storing data with Firebase works. I’ve previously covered how to handle authentication with Firebase and how to create a real time chat application with Firebase but I haven’t really explained how to retrieve data from Firebase yet.

This is what we will be creating:

Master Detail Pattern Example

Before we get started, you should know that Firebase uses NoSQL for data storage. This means that all of the data is stored as objects, rather than a more typical relational database (like MySQL) which stores data in tables. Data stored in Firebase might look something like this:

{
  "people": {
    "person1": {
        name: "Joshua Morony",
        website: "joshmorony.com"
    },
    "person2": {
        name: "Andrew McGivery",
        website: "mcgivery.com"
    }
  }
}

I’m not going to go into any detail about the advantages and disadvantages of this becuase, frankly, there are people who know a lot more about this than I do who have covered it in a lot of detail. The basic idea though is that by storing data as objects it allows for applications to scale much more easily.

A lot of us are probably familiar with how to add and retrieve data in a relational database, but unfortunately a NoSQL database works quite a bit differently – you can’t use queries like `”SELECT * FROM people WHERE name = ‘Joshua Morony'” for example. This means there’s going to be a bit of a learning curve (one I am still making my way through) for getting up to speed with designing data structures and inserting and retrieving data. This tutorial will only cover very basic retrieval of data, but I do plan on releasing tutorials with more complex data structures in future where you might want to run a “query” like you would with MySQL.

Complete the Master Detail Pattern Tutorial

I’m going to be building on top of Andrew’s tutorial so head over to his website and complete that first. You don’t need to worry about setting up the PeopleService to bring in any real data though because we’ll be replacing that with data from Firebase.

Add Firebase to the Application

Once you’ve finished Andrew’s tutorial, the first thing we are going to do is set up Firebase in the application. To do this you will need to include the Firebase and Angular Fire libraries.

Add the following code to your index.html 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>

You will also need to add Firebase as a dependency in your Angular module.

Modify your app.js file to reflect the following:

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

Setting up Firebase

Firebase is all ready to go in our application now, but we still need to hook it up to a Firebase account. If you haven’t got an account already, first head over to the Firebase website and create it now.

Once you’ve got an account created, create a new application in Firebase:

Firebase Create new App

and then click on ‘Manage App’:

Firebase App Screenshot

You should now be in the Data area of your Firebase application’s dashboard:

Firebase Dashboard

This screen provides a graphical representation of what your data looks like. You can also use this screen to manually add some data. So that we have some data to work with, we’re going to add some now by clicking on the + icon that appears when you hover over joshmorony-master-detail: null.

Add the following data to your Firebase application or create your own data:

Firebase Data

NOTE: When using this interface you must add children to the parent object before clicking ‘Add’, Firebase will not let you add empty objects.

You can see that we’ve created a people object that is populated with various Ionic bloggers. For each I have included their name, a link to their website and a photo. Now we’re ready to use this data in our Ionic application.

Pulling Firebase Data into an Ionic Application

The first thing we are going to do is modify the PeopleService from Andrew’s tutorial to use the data in our Firebase application.

Modify the PeopleService factory to reflect the following:

.factory('PeopleService', function($firebaseArray, $firebaseObject){

  var ref = new Firebase('https://joshmorony-master-detail.firebaseio.com');

  return {
    getPeople: function(){ 
      return $firebaseArray(ref.child('people'));
    },
    getPerson: function(personId){
      return $firebaseObject(ref.child('people').child(personId));
    }
  }  
})

In the code above we use $firebaseArray to return an array of all of the people we added, and we use $firebaseObject to return a specific object. The Firebase URL is used as a REST endpoint so we could access all of our people by using this URL:

var ref = new Firebase('https://joshmorony-master-detail.firebaseio.com/people');

and then just using these as the getPeople and getPerson methods instead:

    getPeople: function(){ 
      return $firebaseArray(ref);
    },
    getPerson: function(personId){
      return $firebaseObject(ref.child(personId));
    }

Similarly we could even access a specific person directly by using the URL:

var ref = new Firebase('https://joshmorony-master-detail.firebaseio.com/people/person1')

It doesn’t really matter which way you do it.

Now that we have our PeopleService factory set up correctly, we will need to modify our controllers to work properly with it.

Modify your controllers to reflect the following:

.controller('MasterCtrl', function($scope, PeopleService){
  $scope.people = PeopleService.getPeople();
})

.controller('DetailsCtrl', function($scope, $stateParams, PeopleService){
  var personId = $stateParams.id;
  $scope.person = PeopleService.getPerson(personId);
});

and finally, we will need to make some slight modifications to our master.html and details.html templates.

Modify your master.html template to reflect the following:

<ion-view title="Master">
    <ion-content>
        <ion-list>
            <ion-item class="item" ng-repeat="person in people">
                <a href="#/details/{{person.$id}}">{{person.name}}</a>
            </ion-item>
        </ion-list>
    </ion-content>
</ion-view>

You will notice in the above code we are referencing person.$id$id is a helper method provided by Firebase that will give you the name of the parent object. So if we were looking at my data $id would return person1 – this is useful because this is what we need to provide to Firebase’s REST API to return that specific object.

Modify your details.html template to reflect the following:

<ion-view title="Detail">
    <ion-content>
        <img ng-src="{{person.photo}}" style="float:left; padding: 0 20px;" />
        <h2>{{person.name}}</h2>
        <p>{{person.website}}</p>
    </ion-content>
</ion-view>

All we’re doing here is changing the data used and adding a bit of extra styling.

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

Summary

As you can see, Firebase makes it pretty easy to store and retrieve data. Obviously in this case we have just created the data manually but it’s also quite easy to add data to Firebase from within your application (check out the chat room tutorial with Ionic and Firebase for an example).

Stay tuned for more Ionic + Firebase tutorials in the future!

What to watch next...

  • Pingback: 170 Ionic Framework Resources()

  • Marcel Perez

    I trie this and works fine, however when I move it into a sidemenu project it doesn’t show the detail, it redirect me to my default page (in this example app.browse). I have the following, please help me, what am I doing wrong?

    .config(function($stateProvider, $urlRouterProvider) {
    $stateProvider
    .state(‘app’, {
    url: ‘/app’,
    abstract: true,
    templateUrl: ‘templates/menu.html’,
    controller: ‘AppCtrl’
    })

    .state(‘app.browse’, {
    url: ‘/browse’,
    views: {
    ‘menuContent’: {
    templateUrl: ‘templates/browse.html’
    }
    }
    })

    .state(‘app.master’, {
    url: ‘/master’,
    views: {
    ‘menuContent’: {
    templateUrl: ‘templates/master.html’,
    controller: ‘MasterCtrl’
    }
    }
    })
    // MY PROBLEM IS IN THE FOLLOWING STATE DEFINITION
    state(‘app.details’, {
    url: ‘/details/:id’,
    views: {
    ‘menuContent’: {
    templateUrl: ‘templates/details.html’,
    controller: ‘DetailsCtrl’
    }
    }
    });

    $urlRouterProvider.otherwise(‘/app/browse’);
    });

    • Do You Found Any Solution i also Stuck on that Point

      • Marcel Perez

        Yes Mursaleen, I found it. Even better than my own explanation is on the original solution source.

        Please check the following video from minute 35 and so on. In that point is were the routing start to be building, factories, controllers and htmls after that. This is a simple and efficient solution. If you still have problems, please let me know and I will love to share with you some further details.

      • Thanks Dear but i have Been Already Found just Simple Solution Use Routing Sref Tag with Param ID to Activate this..Thanks

  • When we Click on LInk its Redirect to Another Page.

  • Pingback: 200+ Ionic Framework Resources | Yahaay CodeStash()

  • Navi

    Josh thank you for sharing knowledge in a simple and objective way, I am very grateful to you for having been able to develop my first app for a college project, a suggestion u could do one more part of this tutorial with scroll Infinite lists, status of charging, and the detail pages some functions such as tanning, map, check-in etc. always using firebase ..

  • Veysel Kaya

    can you share this project on github….?

  • muzi jack

    what could be the issue if im getting this error “Firebase.child failed —: First argument was an invalid path: “undefined”. Paths must be non-empty strings and can’t contain “.”, “#”, “$”, “[“, or “]””

  • valmy roi

    Any update with ionic V3 ?

  • valmy roi

    Has anyone achived this with ionic 3 ?

  • Marchele

    It says it was updated but its still showing ionic 1 and not 2 or 3?