Integrate facebook with cordova and angular (Ionic)

I'm trying to add facebook integration to my ionic mobile app that I'm building using cordova. I'm able to get it working either without cordovaa or angular but in no way with both. With the code below, everything goes fine till FB.init gets called after loading all.js . After that, no further code is executed inside _init function, and because of that I cannot subscribe to events or do anything else.

angular facebook directive (uses code from this gist : https://gist.github.com/ruiwen/4722499)

angular.module('facebook', [])
    .directive('fb', ['$FB', function($FB) {
        return {
            restrict: "E",
            replace: true,
            template: "<div id='fb-root'></div>",
            compile: function(tElem, tAttrs) {
                return {
                    post: function(scope, iElem, iAttrs, controller) {
                        var fbAppId = iAttrs.appId || '';

                        var fb_params = {
                            appId: iAttrs.appId || "",
                            cookie: iAttrs.cookie || true,
                            status: iAttrs.status || true,
                            nativeInterface: CDV.FB,
                            useCachedDialogs: false,
                            xfbml: iAttrs.xfbml || true
                        };

                        // Setup the post-load callback
                        window.fbAsyncInit = function() {
                            $FB._init(fb_params);

                            if('fbInit' in iAttrs) {
                                iAttrs.fbInit();
                            }
                        };

                        (function(d, s, id, fbAppId) {
                            var js, fjs = d.getElementsByTagName(s)[0];
                            if (d.getElementById(id)) return;
                            js = d.createElement(s); js.id = id; js.async = true;
                            js.src = "//connect.facebook.net/en_US/all.js";
                            fjs.parentNode.insertBefore(js, fjs);
                        }(document, 'script', 'facebook-jssdk', fbAppId));
                    }
                }
            }
        };
    }])

    .factory('$FB', ['$rootScope', function($rootScope) {

        var fbLoaded = false;

        // Our own customisations
        var _fb =  {
            loaded: fbLoaded,
            isLoaded : function(){
                return this.loaded;
            },
            authenticated : false,
            isAuthenticated : function(){
              return this.authenticated;
            },
            statusUpdated: function(response){
              if (response.status == 'connected') {
                self.authenticated = true;
                alert('logged in');
              } else {
                alert('not logged in');
              }
            },
            _init: function(params) {

                self = this;

                if(window.FB) {


                    // FIXME: Ugly hack to maintain both window.FB
                    // and our AngularJS-wrapped $FB with our customisations
                    angular.extend(window.FB, this);
                    angular.extend(this, window.FB);

                    // Set the flag
                    this.loaded = true;

                    // Initialise FB SDK

                    FB.init(params);

                    //THIS CODE IS NOT CALLED
                    FB.Event.subscribe('auth.statusChange', function(response) {
                        alert('auth.statusChange event');
                    });

                    FB.Event.subscribe('auth.authStatusChange', self.statusUpdated)

                    if(!$rootScope.$$phase) {
                        $rootScope.$apply();
                    }
                }
            }
        }

        return _fb;
    }]);

My controller :

angular.module('starter.controllers', [])

.controller('StartCtrl', [
  '$scope',
  '$FB',
  '$location',
  function($scope, $FB, $location) {
  $scope.$watch(function() {
    return $FB.isLoaded()
  },function(value){

    console.log("VALUE",value);
    // It needs authentication, this won't work.
    if(value){
      $scope.facebook_friends = $FB.api('/me/friends', function(response) {
        $scope.facebook_friends = response.data;
      });
    }
  },true);

  $scope.$watch(function() {
    return $FB.isAuthenticated()
  },function(value){

    alert("VALUE isAuthenticated "+value);
    // YEP, this will work.
    if(value){
      $scope.facebook_friends = $FB.api('/me', function(response) {
        $scope.facebook_friends = response.data;
        console.log("FRIENDS",response);
      });
    }
  },true);

    $scope.FBlogin = function() {
      FB.login(null, {scope: 'email'});
    };

    }
])

index.html :

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=0.5, maximum-scale=0.5, user-scalable=no, width=device-width">
    <title>Starter</title>

    <link href="lib/css/ionic.css" rel="stylesheet">
    <link href="css/app.css" rel="stylesheet">

    <script src="lib/js/ionic.bundle.js"></script>

    <script src="cordova.js"></script>
    <script src="js/angular-fb.js"></script>
    <script src="js/app.js"></script>
    <script src="js/services.js"></script>
    <script src="js/controllers.js"></script>

    <!-- cordova facebook plugin -->
    <script src="cdv-plugin-fb-connect.js"></script>
    <!-- facebook js sdk -->
    <script src="facebook-js-sdk.js"></script> 
  </head>

  <body ng-app="starter" animation="slide-left-right-ios7">

    <ion-nav-view></ion-nav-view>

    <fb app-id='appid'></fb>

  </body>
</html>

and app.js

angular.module('starter', ['ionic', 'starter.services', 'starter.controllers', 'facebook'])

.config(function($stateProvider, $urlRouterProvider) {


  $stateProvider

    .state('start', {
      url: "/start",
      templateUrl: "templates/start.html",
      controller: 'StartCtrl'
    })

  // if none of the above states are matched, use this as the fallback
  $urlRouterProvider.otherwise('/start');
});

You should integrate with Facebook through the facebookConnectPlugin of cordova. You will find a deep explanation of how to use it in this link: https://github.com/Wizcorp/phonegap-facebook-plugin.

The plugin gives you everything you need and short examples. But you have to make sure the following things will be done:

  • Read carefully the instructions of installing the plugin. I choosed the manual way to install the plugin for Android through the cordova CLI.
  • Remember that you can use all phonegap plugins only after the deviceReady event, so you have to make sure you are calling the api of the facebookConnectPlugin after the device is ready of course.

Good luck!

une ngcordova, it gives you simple AngularJS wrappers for a massive amount of Cordova plugins, it include a wrapper for facebookConnectPlugin

The phonegap-facebook-plugin version 0.8.1 has more to do than a simple installation via cordova plugin add. phonegap-native-fb-ionic mentions the required one for ionic step by step.