将facebook与cordova和angular(Ionic)集成在一起

时间:2014-05-27 18:48:33

标签: angularjs cordova facebook-javascript-sdk ionic-framework

我试图将facebook集成添加到我使用cordova构建的离子移动应用程序中。我能够让它在没有cordovaa或角度的情况下工作,但两者都没有。使用下面的代码,一切都很顺利,直到加载all.js后调用FB.init。之后,在_init函数中不再执行任何代码,因此我无法订阅事件或执行任何其他操作。

angular facebook指令(使用此要点中的代码: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;
    }]);

我的控制器:

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>

和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');
});

5 个答案:

答案 0 :(得分:2)

你实际上不应该这样做<script src="facebook-js-sdk.js"></script>,因为它反对TOS。即使你想确保sdk正在加载。

相反,您可以尝试以下代码(以确保您可以先安装cordova-inappbrowser)

<script>
  function statusChangeCallback(response) {
    console.log('statusChangeCallback');
    console.log(response);
    if (response.status === 'connected') {
      // Logged into your app and Facebook.
      testAPI();
    } else if (response.status === 'not_authorized') {
      // The person is logged into Facebook, but not your app.
      document.getElementById('status').innerHTML = 'Please log ' +
        'into this app.';
    } else {

      document.getElementById('status').innerHTML = 'Please log ' +
        'into Facebook.';
    }
  }
  
  function checkLoginState() {
    FB.getLoginStatus(function(response) {
      statusChangeCallback(response);
    });
  }

  window.fbAsyncInit = function() {
  FB.init({
    appId      : '{your-app-id}',
    cookie     : true,  // enable cookies to allow the server to access 
                        // the session
    xfbml      : true,  // parse social plugins on this page
    version    : 'v2.5' // use graph api version 2.5
  });

  FB.getLoginStatus(function(response) {
    statusChangeCallback(response);
  });

  };

  (function(d, s, id) {
    var js, fjs = d.getElementsByTagName(s)[0];
    if (d.getElementById(id)) return;
    js = d.createElement(s); js.id = id;
    js.src = "//connect.facebook.net/en_US/sdk.js";
    fjs.parentNode.insertBefore(js, fjs);
  }(document, 'script', 'facebook-jssdk'));
  
  function testAPI() {
    console.log('Welcome!  Fetching your information.... ');
    FB.api('/me', function(response) {
      console.log('Successful login for: ' + response.name);
      document.getElementById('status').innerHTML =
        'Thanks for logging in, ' + response.name + '!';
    });
  }
</script>

<!--
  Below we include the Login Button social plugin. This button uses
  the JavaScript SDK to present a graphical Login button that triggers
  the FB.login() function when clicked.
-->

<fb:login-button scope="public_profile,email" onlogin="checkLoginState();">
</fb:login-button>

<div id="status">
</div>

To deeper insight

答案 1 :(得分:2)

1首先添加此插件 cordova插件添加cordova-plugin-inappbrowser

2之后创建应用程序ID,请按照以下步骤操作 https://developers.facebook.com/docs/apps/register

3之后,在需要facebook集成的地方添加此代码

&#13;
&#13;
$http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

    $cordovaOauth.facebook("447073565475718", ["email", "public_profile"]).then(function(result) {
         displayData($http, result.access_token);
		var name = result.data.name;
				var gender = result.data.gender;
			 var location = result.data.location;
				var picture = result.data.picture;

    }, function(error) {
        console.log(error);
    });
	};
	 function displayData($http, access_token)
	        {
				$http.get("https://graph.facebook.com/v2.2/me", {params: {access_token: access_token, fields: "name,gender,location,picture,email", format: "json" }}).then(function(result) 
						{

					console.log(JSON.stringify(result));
	            	var name = result.data.name;
	            	var gender = result.data.gender;
	            	var location = result.data.location;
	            	var picture = result.data.picture;
                  	var id =result.data.id;
                  	var userid=id;

                     
	            }, function(error) {
	                alert("There was a problem getting your profile.  Check the logs for details.");
	                console.log(error);
	            });
&#13;
&#13;
&#13;

`

答案 2 :(得分:1)

une ngcordova,它为大量的Cordova插件提供了简单的AngularJS包装器,它包含了facebookConnectPlugin的包装器

答案 3 :(得分:1)

phonegap-facebook-plugin版本0.8.1比通过cordova插件添加的简单安装更多。 phonegap-native-fb-ionic逐步提到离子所需的一个。

答案 4 :(得分:0)

您应该通过cordova的facebookConnectPlugin与Facebook集成。 您将在此链接中找到有关如何使用它的深入说明:https://github.com/Wizcorp/phonegap-facebook-plugin

该插件为您提供所需的一切和​​简短示例。但你必须确保完成以下事项:

  • 请仔细阅读安装插件的说明。我选择了通过cordova CLI手动安装Android插件的方法。
  • 请记住,您只能在deviceReady事件之后使用所有的phonegap插件,因此您必须确保在设备准备就绪后调用facebookConnectPlugin的api。
祝你好运!