17

I wondered if anyone has found a workaround to the behaviour that I'm experiencing.

Take the example of the below code:

<script>
window.fbAsyncInit = function() {
        FB.init({
          appId      : '[----removed-------]', // App ID
          channelUrl : 'http://localhost/channel.html', // Channel File
          status     : true, // check login status
          cookie     : true, // enable cookies
          xfbml      : true  // parse XFBML
        });     
        // Additional initialization code here

        FB.Event.subscribe('auth.statusChange',fbLoginStatus);

        console.log("getloginstatus");

        FB.getLoginStatus(fbLoginStatus);
</script>

Using FB.init with status set to true, essentially calls getLoginStatus() according to the facebook documentation. However, it is apparently intended behaviour that this will not trigger the event auth.statusChange, because the default value is 'unknown', and the value for 'not logged in' is also 'unknown' (even though it can be known!!)

Therefore I have had to make a call to FB.getLoginStatus() explicitly as well as having the status set to true if I want to also respond to users who are not logged in to facebook.

The problem is, this results in the function being called twice if the user is anything other than "logged out".

Is there a neat way to stop this happening? I think my only option might be to call a different function to handle auth change events..

Kara
  • 6,115
  • 16
  • 50
  • 57
Ed_
  • 18,798
  • 8
  • 45
  • 71
  • weird - this bug seems to have been removed. this whole thing is a disaster. I am left with no clue as to when `status:true` is actually useful. they say : 'If you set status to true in the FB.init() call, the SDK will attempt to get info about the current user immediately after init. Doing this can reduce the time it takes to check for the state of a logged in user if you're using Facebook Login, but isn't useful for pages that only have social plugins on them.' so does this mean the response is cached? – Simon_Weaver May 26 '15 at 06:03

3 Answers3

15

My best solution for this was to set status to 'false' in the fb.init options, then to explicitly call getloginstatus separately.

IF get loginstatus came back as unknown (i.e. logged out), I subscribed to the status change event, as well as doing the usual of displaying the login button. Then when the user logs in, status change fires as expected.

Ed_
  • 18,798
  • 8
  • 45
  • 71
4

A better solution that theoretically should save you a roundtrips is as follows (coffeescript, but easily translatable to javascript):

FB.init
  appId: appId
  channelUrl: channelUrl
  status: true     # Check Facebook Login status on init
  cookies: true
  xfbml: false

FB.getLoginStatus (response) =>
  @parseResponse(response)
  FB.Event.subscribe 'auth.statusChange', @parseResponse
  FB.Event.subscribe 'auth.authResponseChange', @parseResponse

We're still using a manual getLoginStatus to fire when the user is unknown, but this time we still use 'status: true' so that the login status is already cached when getLoginStatus is called. By subscribing to the relevant events only after getLoginStatus has fired, we make sure the handling method parseResponse is only called once on load.

0

You can check the response you get back after you pass a true parameter in the getLoginStatus:

window.fbAsyncInit = function() {
    FB.init({
        appId  : '',
        status : true,
        cookie : true,
        xfbml  : true,
    });

    FB.getLoginStatus( function(response) {
        //console.log(response);
        if (response.status === 'connected') {
            var accessToken = response.authResponse.accessToken;
            alert(accessToken);
        } else if (response.status === 'not_authorized') {
            //login function
        } else {
            //login function
        }
    }, true);

    FB.Event.subscribe('auth.authResponseChange', function(response) {
        //console.log('The status of the session changed to: '+response.status);
        window.location.reload();
    });
};

If you set the status to true, the FB.getLoginStatus response object will be cached by the SDK and subsequent calls to FB.getLoginStatus will return data from this cached response.

To get around this, you have to call FB.getLoginStatus with the second parameter set to true to force a roundtrip to Facebook - effectively refreshing the cache of the response object.

FB Docs: https://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus/

Philip
  • 5,011
  • 2
  • 30
  • 36
  • 4
    caching wasn't the issue I described above. Setting status = true in fb.init should force a login status check, then the status change event should trigger when that check happens. – Ed_ Jun 18 '12 at 23:00
  • status = true is cached, for this reason you need the true parameter in the getLoginStatus(). – Philip Jul 01 '12 at 13:59