How to detect when facebook's FB.init is complete

后端 未结 12 2013
我寻月下人不归
我寻月下人不归 2020-11-28 01:28

The old JS SDK had a function called FB.ensureInit. The new SDK does not seem to have such function... how can I ensure that I do not make api calls until it is fully initia

相关标签:
12条回答
  • 2020-11-28 02:09

    You can subscribe to the event:

    ie)

    FB.Event.subscribe('auth.login', function(response) {
      FB.api('/me', function(response) {
        alert(response.name);
      });
    });
    
    0 讨论(0)
  • 2020-11-28 02:11

    While some of the above solutions work, I thought I'd post our eventual solution - which defines a 'ready' method that will fire as soon as FB is initialized and ready to go. It has the advantage over other solutions that it's safe to call either before or after FB is ready.

    It can be used like so:

    f52.fb.ready(function() {
        // safe to use FB here
    });
    

    Here's the source file (note that it's defined within a 'f52.fb' namespace).

    if (typeof(f52) === 'undefined') { f52 = {}; }
    f52.fb = (function () {
    
        var fbAppId = f52.inputs.base.fbAppId,
            fbApiInit = false;
    
        var awaitingReady = [];
    
        var notifyQ = function() {
            var i = 0,
                l = awaitingReady.length;
            for(i = 0; i < l; i++) {
                awaitingReady[i]();
            }
        };
    
        var ready = function(cb) {
            if (fbApiInit) {
                cb();
            } else {
                awaitingReady.push(cb);
            }
        };
    
        window.fbAsyncInit = function() {
            FB.init({
                appId: fbAppId,
                xfbml: true,
                version: 'v2.0'
            });
    
            FB.getLoginStatus(function(response){
                fbApiInit = true;
                notifyQ();
            });
        };
    
        return {
            /**
             * Fires callback when FB is initialized and ready for api calls.
             */
            'ready': ready
        };
    
    })();
    
    0 讨论(0)
  • 2020-11-28 02:12

    Actually Facebook has already provided a mechanism to subscribe to authentication events.

    In your case you are using "status: true" which means that FB object will request Facebook for user's login status.

    FB.init({
        appId  : '<?php echo $conf['fb']['appid']; ?>',
        status : true, // check login status
        cookie : true, // enable cookies to allow the server to access the session
        xfbml  : true  // parse XFBML
    });
    

    By calling "FB.getLoginStatus()" you are running the same request again.

    Instead you could use FB.Event.subscribe to subscribe to auth.statusChange or auth.authResponseChange event BEFORE you call FB.init

    FB.Event.subscribe('auth.statusChange', function(response) {
        if(response.status == 'connected') {
            runFbInitCriticalCode();
        }
    });
    
    FB.init({
        appId  : '<?php echo $conf['fb']['appid']; ?>',
        status : true, // check login status
        cookie : true, // enable cookies to allow the server to access the session
        xfbml  : true  // parse XFBML
    });
    

    Most likely, when using "status: false" you can run any code right after FB.init, because there will be no asynchronous calls.

    0 讨论(0)
  • 2020-11-28 02:15

    Update on Jan 04, 2012

    It seems like you can't just call FB-dependent methods (for example FB.getAuthResponse()) right after FB.init() like before, as FB.init() seems to be asynchronous now. Wrapping your code into FB.getLoginStatus() response seems to do the trick of detecting when API is fully ready:

    window.fbAsyncInit = function() {
        FB.init({
            //...
        });
    
        FB.getLoginStatus(function(response){
            runFbInitCriticalCode(); 
        });
    
    };  
    

    or if using fbEnsureInit() implementation from below:

    window.fbAsyncInit = function() {
        FB.init({
            //...
        });
    
        FB.getLoginStatus(function(response){
            fbApiInit = true;
        });
    
    };  
    

    Original Post:

    If you want to just run some script when FB is initialized you can put some callback function inside fbAsyncInit:

      window.fbAsyncInit = function() {
        FB.init({
          appId  : '<?php echo $conf['fb']['appid']; ?>',
          status : true, // check login status
          cookie : true, // enable cookies to allow the server to access the session
          xfbml  : true  // parse XFBML
        });
        FB.Canvas.setAutoResize();
    
        runFbInitCriticalCode(); //function that contains FB init critical code
      };
    

    If you want exact replacement of FB.ensureInit then you would have to write something on your own as there is no official replacement (big mistake imo). Here is what I use:

      window.fbAsyncInit = function() {
        FB.init({
          appId  : '<?php echo $conf['fb']['appid']; ?>',
          status : true, // check login status
          cookie : true, // enable cookies to allow the server to access the session
          xfbml  : true  // parse XFBML
        });
        FB.Canvas.setAutoResize();
    
        fbApiInit = true; //init flag
      };
    
      function fbEnsureInit(callback) {
            if(!window.fbApiInit) {
                setTimeout(function() {fbEnsureInit(callback);}, 50);
            } else {
                if(callback) {
                    callback();
                }
            }
        }
    

    Usage:

    fbEnsureInit(function() {
        console.log("this will be run once FB is initialized");
    });
    
    0 讨论(0)
  • 2020-11-28 02:17

    Small but IMPORTANT notices:

    1. FB.getLoginStatus must be called after FB.init, otherwise it will not fire the event.

    2. you can use FB.Event.subscribe('auth.statusChange', callback), but it will not fire when user is not logged in facebook.

    Here is the working example with both functions

    window.fbAsyncInit = function() {
        FB.Event.subscribe('auth.statusChange', function(response) {
            console.log( "FB.Event.subscribe auth.statusChange" );
            console.log( response );
        });
    
        FB.init({
            appId   : "YOUR APP KEY HERE",
            cookie  : true,  // enable cookies to allow the server to access
                    // the session
            xfbml   : true,  // parse social plugins on this page
            version : 'v2.1', // use version 2.1
            status  : true
        });
    
        FB.getLoginStatus(function(response){
            console.log( "FB.getLoginStatus" );
            console.log( response );
        });
    
    };
    
    // Load the SDK asynchronously
    (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'));
    
    0 讨论(0)
  • 2020-11-28 02:18

    Sometimes fbAsyncInit doesnt work. I dont know why and use this workaround then:

     var interval = window.setInterval(function(){
        if(typeof FB != 'undefined'){
            FB.init({
                appId      : 'your ID',
                cookie     : true,  // enable cookies to allow the server to access// the session
                xfbml      : true,  // parse social plugins on this page
                version    : 'v2.3' // use version 2.3
            });
    
            FB.getLoginStatus(function(response) {
                statusChangeCallback(response);
            });
            clearInterval(interval);
        }
    },100);
    
    0 讨论(0)
提交回复
热议问题