फेसबुक का FB.init पूरा होने पर कैसे पता करें


115

पुराने JS SDK के पास FB.ensureInit नामक एक फंक्शन था। नए एसडीके के पास ऐसा कार्य नहीं है ... मैं कैसे सुनिश्चित कर सकता हूं कि जब तक यह पूरी तरह से शुरू न हो जाए, मैं एपी कॉल नहीं करता?

मैं इसे हर पृष्ठ के शीर्ष में शामिल करता हूं:

<div id="fb-root"></div>
<script>
  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();
  };

  (function() {
    var e = document.createElement('script');
    e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
    e.async = true;
    document.getElementById('fb-root').appendChild(e);
  }());
</script>

इस समस्या के मेरे समाधान के लिए इस लिंक को देखें। facebook.stackoverflow.com/questions/12399428/…
रेमी ग्रुमू

जवाबों:


138

04 जनवरी 2012 को अद्यतन

ऐसा लगता है कि आप पहले की तरह ही एफबी-निर्भर तरीकों (उदाहरण के लिए FB.getAuthResponse()) को ठीक से कॉल नहीं कर सकते FB.init(), जैसा कि FB.init()अब अतुल्यकालिक लगता है। आपके कोड को FB.getLoginStatus()प्रतिक्रिया में लपेटकर लगता है कि एपीआई पूरी तरह से तैयार होने पर पता लगाने की चाल है:

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

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

};  

या fbEnsureInit()नीचे से कार्यान्वयन का उपयोग करते समय:

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

    FB.getLoginStatus(function(response){
        fbApiInit = true;
    });

};  

मूल पोस्ट:

यदि आप FB आरंभीकृत होने पर कुछ स्क्रिप्ट चलाना चाहते हैं, तो आप कुछ कॉलबैक फ़ंक्शन को अंदर रख सकते हैं 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
  };

यदि आप FB.ensureInit का सटीक प्रतिस्थापन चाहते हैं तो आपको स्वयं ही कुछ लिखना होगा क्योंकि कोई आधिकारिक प्रतिस्थापन (बड़ी गलती imo) नहीं है। यहाँ मेरा उपयोग है:

  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();
            }
        }
    }

उपयोग:

fbEnsureInit(function() {
    console.log("this will be run once FB is initialized");
});

2
धन्यवाद सर्ग .. आप एक किंवदंती हैं!
पाब्लो

3
FB.init कहे जाने के तुरंत बाद मैं फेसबुक एपीआई रिक्वेस्ट नहीं चला पा रहा हूं - शायद इसलिए कि मैं जिस विधि का उपयोग कर रहा हूं वह 'fql.it' है? किसी भी तरह से, मुझे fbApiInit ध्वज पर एक लंबा समय निर्धारित करना होगा।
इयान हंटर

अद्यतन के लिए धन्यवाद - मुझे वही समस्या हो रही थी और आपके अद्यतन समाधान ने पूरी तरह से काम किया!
टेरी एन

@beanland, fql.query एपि कॉल के लिए आवश्यक है कि उपयोगकर्ता ने लॉग इन किया हो। क्या आप सुनिश्चित हैं कि आप responseपीछे से आने के बाद क्वेरी चला रहे हैं FB.getLoginStatus(function(response){}? - ऊपर "मूल उत्तर" बनाम "अपडेट किए गए उत्तर" अंतर पर ध्यान दें।
tjmehta

@serg उदाहरण के लिए धन्यवाद। मुझे अपने कार्य में देरी के fbAsyncInitलिए अंदर ले जाना पड़ा क्योंकि इसे लोड के बाद कहा जाता हैwindow.fbAsyncInit = function() { FB.init({ appId : '*************', channelUrl : 'http://www.mydomain.com', status : true, // check login status cookie : true, // enable cookies to allow the server to access the session oauth : true, // enable OAuth 2.0 xfbml : true // parse XFBML }); setTimeout(function() { myfunction(function (callback) {}, '', '', '' ); }, 1200); };
tq

38

दरअसल फेसबुक पहले ही प्रमाणीकरण घटनाओं की सदस्यता के लिए एक तंत्र प्रदान कर चुका है।

आपके मामले में आप " स्थिति: सत्य " का उपयोग कर रहे हैं, जिसका अर्थ है कि FB ऑब्जेक्ट उपयोगकर्ता की लॉगिन स्थिति के लिए फेसबुक से अनुरोध करेगा।

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.getLoginStatus ()" कॉल करके आप फिर से वही अनुरोध चला रहे हैं ।

इसके बजाय आप इस्तेमाल कर सकते हैं FB.Event.subscribe की सदस्यता के लिए auth.statusChange या auth.authResponseChange घटना से पहले आप 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
});

सबसे अधिक संभावना है, " स्थिति: गलत " का उपयोग करते समय आप FB.init के ठीक बाद किसी भी कोड को चला सकते हैं, क्योंकि कोई एसिंक्रोनस कॉल नहीं होगा।


नोट: इस विधि के साथ एकमात्र चेतावनी यह है कि, यदि आप लॉग इन नहीं हैं, तो ईवेंट ट्रिगर नहीं होगा। बस अपने डिफ़ॉल्ट UI स्थिति को प्रमाणित करें जैसे कि प्रमाणित नहीं है, और यह पूरी तरह से काम करता है। फिर आप ईवेंट हैंडलर के अंदर कनेक्टेड या not_authorized की जांच कर सकते हैं।
डेविड सी

इसके अलावा, फ्रंट-एंड ऐप्स के लिए, रीफ्रेश के बीच उपयोगकर्ता लॉगिन स्थिति बनाए रखने के cookieलिए true, इनिट परम ऑब्जेक्ट में सेट करें ।
एमके सफी

12

आपके द्वारा उपयोग किए जाने के मामले में यहां एक समाधान है और फेसबुक अतुल्यकालिक आलसी लोड हो रहा है:

// listen to an Event
$(document).bind('fbInit',function(){
    console.log('fbInit complete; FB Object is Available');
});

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

    $(document).trigger('fbInit'); // trigger event
};

3
मुझे यह पसंद है! एकमात्र मुद्दा यह है कि फेसबुक इस बात पर जोर देता है कि आपको अपने FB init कोड को सीधे खोलने के बाद शामिल होना चाहिए <body> टैग, और सबसे अच्छा अभ्यास यह कहता है कि आपको <body> टैग को बंद करने से पहले jQuery को लोड करना चाहिए। रवींद्र! मुर्गी और अंडा। मैं आपको "स्क्रू यू, फेसबुक" कहने के लिए लुभा रहा हूं और jQuery के बाद FB लोड कर रहा हूं।
एथन ब्राउन

@EthanBrown मैं सहमत हूं - आपके पेज को शायद jQuery की जरूरत है, इससे ज्यादा FB की जरूरत है ताकि समझ में आए। मैं पहले पेज साल के अंत में jQuery लोड करने के लिए कोशिश कर रहा ;-) छोड़ दिया
Simon_Weaver

version: 'v2.5'init json में जोड़ें अन्य बुद्धिमान यह काम नहीं करेगा .. पर leat मेरे लिए नहीं था। मदद के लिए धन्यवाद
विकास बंसल

10

यह जांचने का एक अन्य तरीका है कि क्या एफबी ने आरंभिक रूप से निम्नलिखित कोड का उपयोग किया है:

ns.FBInitialized = function () {
    return typeof (FB) != 'undefined' && window.fbAsyncInit.hasRun;
};

इस प्रकार आपके पेज रेडी इवेंट में आप ns.FBInitialized चेक कर सकते हैं और सेटटाइमऑउट का उपयोग करके इवेंट को बाद के चरण में स्थगित कर सकते हैं।


यह असली बात है! धन्यवाद!
थियागो मकदूनियो

यह सरल है। इसे पसंद करें
Faris Rayhan

5

हालांकि उपरोक्त कुछ समाधान काम करते हैं, मैंने सोचा कि मैं अपना अंतिम समाधान पोस्ट करूंगा - जो एक 'तैयार' पद्धति को परिभाषित करता है जो कि एफबी के आरंभ होते ही आग लग जाएगी और जाने के लिए तैयार हो जाएगी। अन्य समाधानों पर इसका लाभ यह है कि एफबी तैयार होने से पहले या बाद में कॉल करना सुरक्षित है।

यह इस तरह से इस्तेमाल किया जा सकता है:

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

यहाँ स्रोत फ़ाइल (ध्यान दें कि इसे 'f52.fb' नामस्थान के भीतर परिभाषित किया गया है)।

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
    };

})();

4

मैंने वैश्विक फ़ंक्शन का उपयोग करके सेटटाइमआउट का उपयोग करने से परहेज किया है:

संपादित करें नोट: मैंने निम्नलिखित सहायक लिपियों को अपडेट किया है और एक वर्ग बनाया है जो उपयोग करने में आसान / सरल है; इसे यहाँ देखें ::: https://github.com/tjmehta/fbExec.js

window.fbAsyncInit = function() {
    FB.init({
        //...
    });
    window.fbApiInit = true; //init flag
    if(window.thisFunctionIsCalledAfterFbInit)
        window.thisFunctionIsCalledAfterFbInit();
};

fbEnsureInit FB.init के बाद इसे कॉलबैक कहेगा

function fbEnsureInit(callback){
  if(!window.fbApiInit) {
    window.thisFunctionIsCalledAfterFbInit = callback; //find this in index.html
  }
  else{
    callback();
  }
}

fbEnsureInitAndLoginStatus FB.init के बाद और FB.getLoginStatus के बाद कॉलबैक करेगा।

function fbEnsureInitAndLoginStatus(callback){
  runAfterFbInit(function(){
    FB.getLoginStatus(function(response){
      if (response.status === 'connected') {
        // the user is logged in and has authenticated your
        // app, and response.authResponse supplies
        // the user's ID, a valid access token, a signed
        // request, and the time the access token
        // and signed request each expire
        callback();

      } else if (response.status === 'not_authorized') {
        // the user is logged in to Facebook,
        // but has not authenticated your app

      } else {
        // the user isn't logged in to Facebook.

      }
    });
  });
}

fbEnsureInit उदाहरण का उपयोग:

(FB.login को FB के आरंभ होने के बाद चलाने की आवश्यकता है)

fbEnsureInit(function(){
    FB.login(
       //..enter code here
    );
});

fbEnsureInitAndLogin उदाहरण का उपयोग:

(FB.api को FB.init के बाद चलाने की जरूरत है और FB उपयोगकर्ता को लॉग इन करना होगा।)

fbEnsureInitAndLoginStatus(function(){
    FB.api(
       //..enter code here
    );
});

1
मैंने इस सहायक वर्ग को लिखा जो एक आसान और साफ-सुथरे तरीके से ऊपर जैसा प्रदर्शन करता है; इसे यहाँ देखें :: github.com/tjmehta/fbExec.js
tjmehta

4

किसी सेटटाइमआउट या सेटइंटरवल का उपयोग करने के बजाय, मैं ऑब्जेक्ट्स को स्थगित कर सकता हूं ( यहां jQuery द्वारा कार्यान्वयन )। यह उचित समय में कतार को हल करने के लिए अभी भी मुश्किल है, क्योंकि init में कॉलबैक नहीं है, लेकिन घटना की सदस्यता के साथ परिणाम जोड़ रहा है (जैसा कि किसी ने मुझसे पहले कहा था), चाल को करना चाहिए और पर्याप्त पास होना चाहिए।

छद्म-स्निपेट इस प्रकार दिखेगा:

FB.Event.subscribe('auth.statusChange', function(response) {
   if (response.authResponse) {
       // user has auth'd your app and is logged into Facebook
   } else {
       // user has not auth'd your app, or is not logged into Facebook
   }
   DeferredObject.resolve();
});

4

यहां एक सरल विधि है, जिसके लिए न तो घटनाओं की आवश्यकता होती है और न ही समय की। हालाँकि इसके लिए jQuery की आवश्यकता होती है।

उपयोग jQuery.holdReady() (डॉक्स)

तो, अपने jQuery स्क्रिप्ट के तुरंत बाद, तैयार घटना में देरी करें।

<!-- jQuery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
    $.holdReady( true ); // don't fire ready until told (ie when FB loaded)
</script>

फिर, अपने फेसबुक इनिट फ़ंक्शन में, इसे जारी करें:

window.fbAsyncInit = function() {
    FB.init({
        appId: '11111111111111',
        cookie: true,
        xfbml: false,
        version: 'v2.4'
    });

    // release the ready event to execute
    $.holdReady( false );
};

फिर आप सामान्य रूप से तैयार घटना का उपयोग कर सकते हैं:

$(document).ready( myApp.init );

2

आप इस कार्यक्रम की सदस्यता ले सकते हैं:

अर्थात)

FB.Event.subscribe('auth.login', function(response) {
  FB.api('/me', function(response) {
    alert(response.name);
  });
});

2

छोटे लेकिन महत्वपूर्ण नोटिस:

  1. FB.getLoginStatusके बाद बुलाया जाना चाहिए FB.init, अन्यथा यह घटना को आग नहीं देगा।

  2. आप उपयोग कर सकते हैं FB.Event.subscribe('auth.statusChange', callback), लेकिन जब उपयोगकर्ता फ़ेसबुक पर लॉग इन नहीं होगा तो यह आग नहीं लगाएगा।

यहां दोनों कार्यों के साथ काम करने का उदाहरण दिया गया है

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

1

Facebook API FB._apiKey के लिए देखता है ताकि आप API के अपने एप्लिकेशन को किसी चीज़ से कॉल करने से पहले इसके लिए देख सकें:

window.fbAsyncInit = function() {
  FB.init({
    //...your init object
  });
  function myUseOfFB(){
    //...your FB API calls
  };
  function FBreadyState(){
    if(FB._apiKey) return myUseOfFB();
    setTimeout(FBreadyState, 100); // adjust time as-desired
  };
  FBreadyState();
}; 

सुनिश्चित नहीं है कि इससे कोई फर्क पड़ता है, लेकिन मेरे मामले में - क्योंकि मैं यह सुनिश्चित करना चाहता था कि UI तैयार था - मैंने jQuery के दस्तावेज के साथ आरंभीकरण को तैयार किया है (अंतिम थोड़ा ऊपर):

  $(document).ready(FBreadyState);

यह भी ध्यान दें कि मैं फेसबुक के all.js को लोड करने के लिए async = true का उपयोग नहीं कर रहा हूं, जो मेरे मामले में UI में साइन इन करने और अधिक मज़बूती से ड्राइविंग सुविधाओं के साथ मदद करता प्रतीत होता है।


1

कभी-कभी fbAsyncInit काम नहीं करता है। मैं नहीं जानता कि क्यों और इस समाधान का उपयोग करें:

 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);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.