0
votes

I am very new to ember and trying to implement authentication via facebook

I am using ember-facebook.js library to connect with facebook. Once the authentication is successful, I want to transition to some other route e.g. '/index'. This library creates a App.FBUser object in mixin which is populated from the facebook response. The blog say following:

Whenever the user changes (login, logout, app authorization, etc) the method updateFBUser is called, updating the App.FBUser object on your application. You can do whatever you want with this binding, observe it, put it in the DOM, whatever.

Ember.Facebook = Ember.Mixin.create({
  FBUser: void 0,
  appId: void 0,
  fetchPicture: true,
  init: function() {
    this._super();
    return window.FBApp = this;
  },
  appIdChanged: (function() {
    var _this = this;
    this.removeObserver('appId');
    window.fbAsyncInit = function() {
      return _this.fbAsyncInit();
    };
    return $(function() {
      var js;
      js = document.createElement('script');
      $(js).attr({
        id: 'facebook-jssdk',
        async: true,
        src: "//connect.facebook.net/en_US/all.js"
      });
      return $('head').append(js);
    });
  }).observes('appId'),
  fbAsyncInit: function() {
    var _this = this;
    FB.init({
      appId: this.get('appId'),
      status: true,
      cookie: true,
      xfbml: true
    });
    this.set('FBloading', true);

    FB.Event.subscribe('auth.authResponseChange', function(response) {
      return _this.updateFBUser(response);
    });

    return FB.getLoginStatus(function(response) {
      return _this.updateFBUser(response);
    });
  },
  updateFBUser: function(response) {
    console.log("Facebook.updateFBUser: Start");
    var _this = this;
    if (response.status === 'connected') {
      //console.log(_this);
      return FB.api('/me', function(user) {
        var FBUser;
        FBUser = user;
        FBUser.accessToken = response.authResponse.accessToken;
        if (_this.get('fetchPicture')) {
          return FB.api('/me/picture', function(path) {
            FBUser.picture = path;
            _this.set('FBUser', FBUser);
            return _this.set('FBloading', false);
          });
        } else {
          _this.set('FBUser', FBUser);
          return _this.set('FBloading', false);
        }
      });
    } else {
      this.set('FBUser', false);
      return this.set('FBloading', false);
    }
  }//updateFBUser
});

Update :

Adding following observer in my LoginController, I am able to capture the App.FBUser update event(it is update after getting response from FB; as indicated by the blog). From this observer method, when I try to 'transitionTo' my index route I get following error Uncaught TypeError: Object data-size has no method 'transitionTo'. Following is the code

App.LoginController = Ember.Controller.extend({
onSuccess: (function(){
    var self = this;
    /*
        //tried all these method to redirect but error is the same
        var attemptedTransition = this.get('attemptedTransition');
        attemptedTransition.retry();
     */
     /*
    //tried all these method to redirect but error is the same
    var router = this.get('target.router');
    router.transitionTo('index');
    */
    
    //tried all these method to redirect but error is the same
    this.transitionToRoute('index');
}).observes('App.FBUser')
});

Index Route

App.AuthenticatedRoute = Ember.Route.extend({ 
 beforeModel: function(transition){
 var self = this;
 if(!App.FBUser){
  self.redirectToLogin(transition);
 }
},

redirectToLogin: function(transition){
var loginController = this.controllerFor('login');
loginController.set('attemptedTransition', transition);
this.transitionTo('login');
  }
});

I am not able to get my head around it.

Any help is greatly appreciated. Thanks

2

2 Answers

2
votes

How can I access this object in my Route.beforeModel() hook.

Depending on what route's beforModel hook you are talking about, this is how you could do it:

App.SomeRoute = Ember.Route.extend({
  beforeModel: function(transition) {
    if (!Ember.isNone(App.FBUser)) {
      // calling 'transitionTo' aborts the transition, redirects to 'index'
      this.transitionTo('index');
    }
  }
});

Update in response to your last comment

The addon you are using is slightly outdated and the proposed implementation method for the mixin in your application will not work with the current version of ember:

App = Ember.Application.create(Ember.Facebook)
App.set('appId', 'yourfacebookappid');

starting from version 1.0.0-rc3 of ember you should rather do it like this:

App = Ember.Application.creatWithMixins(Ember.Facebook);
App.set('appId', 'yourfacebookappid');

After that you should be able to have access to the App.FBUser object as mentioned above.

Update 2

If you want to be able to be notified when some events happend, like login, logout etc. you should (as the Author of the addon states on it's blog post) override the updateFBUser method and do in there your transitions.

Since the addon is trough the mixin available in our App namespace you should be able to do the following:

App = Ember.Application.creatWithMixins(Ember.Facebook, {
  updateFBUser: function() {
    this._super();
    // we are calling super to let the addon
    // do it's work but at the same time we get
    // notified that something happened, so do at this
    // point your transition
  }
});

Hope it helps.

0
votes

As per Issue 1 adding

attributeBindings: [],

to:

return Ember.FacebookView = Ember.View.extend({ 

solved the issue.