2

I'm wondering why it seems as though the "else if" case of response.status === 'not authorized' and the "else" case ("unknown", ie user is not logged into facebook) are not being executed. When I am logged into my app, testAPI() is called accordingly in the response.stats === 'connected' . However, when I open up incognito mode in Chrome, the testAPI() functions in the other else cases are not being called. Anyone know why?

window.fbAsyncInit = function() {

FB.init({
    appId      : 'appnumberhere', // App ID
    channelUrl : '//localhost/appname/channel.php', // Channel File
    status     : true, // check login status
    cookie     : true, // enable cookies to allow the server to access the session
    xfbml      : true  // parse XFBML
});

FB.Event.subscribe('auth.authResponseChange', function(response) {

    if (response.status === 'connected') {
          testAPI(); // works
    } else if (response.status === 'not_authorized') {
           testAPI(); // not called. Nothing in console.
          FB.login();
    } else {
           testAPI(); // not called. Nothing in console.
          FB.login();
           }
    });


}); // end async init function

the testAPI function:

 function testAPI() {
    console.log('Welcome!  Fetching your information.... ');
    FB.api('/me', function(response) {
      console.log('Good to see you, ' + response.name + '.');
    });
  }

As a side note, I am also not seeing a facebook login dialogue pop up if I am not logged in, which is what I think fb.login() is supposed to invoke.

extra side note

Also, strangely, I need to have <script src="//connect.facebook.net/en_US/all.js"></script> below the FB SDK include <script>(function(d){ var js,....</script> and within my channel file for my app to work. Otherwise, some parts do not load. Not sure if this may be related, but it's very strange.

LazerSharks
  • 3,089
  • 4
  • 42
  • 67
  • 1
    Are you developing on localhost? – 1'' Jun 23 '13 at 04:48
  • 1
    yes in fact I am. I am also getting multiple `Blocked a frame with origin "http://static.ak.facebook.com" from accessing a frame with origin "http://localhost". The frame requesting access set "document.domain" to "facebook.com", but the frame being accessed did not. Both must set "document.domain" to the same value to allow access.` Not sure if that is related. – LazerSharks Jun 23 '13 at 06:03
  • Make sure your Facebook app is configured to point to localhost, and that you don't have any syntax errors in your Javascript init code (the part you posted looks fine). – 1'' Jun 23 '13 at 16:49
  • Hmm, after looking around for a few days still no luck. The only other code part of my init code is FB.init... and it looks exactly the same as the demo code (updated my q above). I've also tried turning on live mode and changing my site url. In this thread http://stackoverflow.com/questions/11682590/facebook-fb-event-subscribeauth-authresponsechange-not-working the bottom answer says I should specify a port. Do you know what port this is? I've tried `http://localhost:80/appname` but no luck. – LazerSharks Jun 26 '13 at 03:17
  • Try setting your canvas URL to `http://localhost:8080`? – 1'' Jun 26 '13 at 03:27
  • Darn. No luck. I'm not using canvas BTW. – LazerSharks Jun 26 '13 at 03:32
  • 1
    So put that in for external website? I'm sorry I can't be more helpful, I'm new to this as well. :) – 1'' Jun 26 '13 at 03:37
  • Oh yeah, I tried to. No it's okay, thanks for trying at least :) It seems a lot of people have had the same problem and none of them could get answers as well. – LazerSharks Jun 26 '13 at 03:39

1 Answers1

1

As this question explains, auth.authResponseChange and auth.statuschange don't fire when the user is not logged in. When a user loads the page, the user starts off in the "unknown" state; but once FB.init is called with status:true, Facebook checks the login status and determines that the user is not logged in - which is also called the "unknown" state! Technically, there's no change of state, so the state-change callbacks are not called. (This seems like a major API design flaw, especially since their own sample code doesn't work.)

One solution, which is the accepted answer to that question, is to set the status check in FB.init to false, and instead manually check the status using FB.getLoginStatus() so that we can respond to it ourselves. If the user is not logged in, then subscribe to the login event. If the user is already logged in, that's great.

Here's the code I'm using. login() and logout() are functions I've defined that render parts of the page for the logged-in and not logged-in states. logout() displays a login button, while login() displays user-specific information.

FB.init({
    appId: '...',
    channelUrl: window.location.protocol + '//' + window.location.host + '/channel.html',
    status: false,
    [... other settings ...]
});

FB.getLoginStatus(function(response) {
    if (response.status === 'connected') {
        login();
    } else {
        FB.Event.subscribe('auth.login', function(response) {
            window.location.reload();
            login();
        });
        logout();
    }
});

Notice the window.location.reload(); in the case where the user was not logged in originally and then logged themselves in. This is to avoid a similar Blocked a frame... error to what you were experiencing, in my case an http:// vs https:// mismatch. See if you need it in your case. If you're still experiencing a Blocked a frame... error, it may be due to the way you've configured your app settings in Facebook. Try putting http://localhost:8080/ as the site URL under "Website with Facebook Login", and access that site to view your app.

Community
  • 1
  • 1
1''
  • 26,823
  • 32
  • 143
  • 200
  • Wow, nice! This is a very thorough answer. After posting this question a while ago I had actually figured out a method very similar to yours, utilizing getLoginStatus and if/else cases. This is indeed the solution, and I agree it is bad design on their part. However, do you think you further explain how `window.location.reload()` avoids the `Blocked a frame...` error? – LazerSharks Jul 09 '13 at 03:53
  • 1
    It avoids my error: `Blocked a frame with origin "http://www.facebook.com" from accessing a frame with origin "https://s-static.ak.facebook.com". The frame requesting access has a protocol of "http", the frame being accessed has a protocol of "https". Protocols must match.` I'm not sure if it will help yours. I'm going to try to figure this out in a subsequent question. – 1'' Jul 09 '13 at 04:11
  • Hmm. Neither solution (`window.location.reload` or `:8080`) resolved the error in my case. When I try `:8080` I get the error: `Given URL is not allowed by the Application configuration.: One or more of the given URLs is not allowed by the App's settings. It must match the Website URL or Canvas URL, or the domain must be a subdomain of one of the App's domains.` – LazerSharks Jul 09 '13 at 04:18
  • However, thank you very much for both of your suggestions! They are very much appreciated. Do you know if the `Blocked a frame...` error is even a crucial error? And how else can the http/mismatch be avoided? – LazerSharks Jul 09 '13 at 04:18
  • I'm going to ask about the http mismatch. Did you put `:8080` or the full `localhost:8080` into the "Website with Facebook Login" site URL box? – 1'' Jul 09 '13 at 04:22
  • 1
    Take a look at [this question](http://stackoverflow.com/questions/17539993/facebook-app-silent-protocols-must-match-error) if you're interested in the blocked a frame error. – 1'' Jul 09 '13 at 04:37