FB init function gives wrong version error

后端 未结 20 1157
故里飘歌
故里飘歌 2020-12-08 18:18

I\'m using the Facebook JS sdk, and I have created a new App today. Everything is configured properly. Using init function like:

window.fbAsyncInit = functio         


        
相关标签:
20条回答
  • 2020-12-08 19:01

    You are using the cordova-plugin-facebook4 plugin, and that is a custom error message that means that the init hasn't finished when the facebook api function is called. Since the plugin does not give a waitForInitialize using setTimeout and then retrying the api method is the best bet.

    var retryFunc = (iteration) => {
        return new Promise((s, f) => facebookConnectPlugin.getLoginStatus(s, f))
        .then(authentication => authentication.status === 'connected')
        .then(isLoggedIn => {
            /* Your Code Here */
        })
        .catch(failure => {
            console.log(`Waiting for Facebook Init. Iteration: ${iteration || 0}`);
            if((iteration || 0) < 10) { 
                return new Promise((s, setTimeout(() => s(), 1000)
                .then(() => retryFunc(null, (iteration || 0) + 1);
            }
            else { return Promise.reject({Error: 'Failed to check login status.', Detail: failure}); }
        });
    };
    
    retryFunc();
    /* Or replace getLoginStatus with your api call. */
    
    • Error Message
    • Additional info
    0 讨论(0)
  • 2020-12-08 19:02

    I had the same problem, and I think I found the root cause!

    Root cause

    In my case, we were injecting FB SDK dynamically to our customer's website. However, some of our customers were already added FB SDK via other plugins. Those plugins have different app id and version.

    So depending on latency some plugins call init before/after ours

    Solution

    If you're the owner of the site where you're injecting the SDK, make sure no other plugins are injecting FB SDK and calling init different version and app id

    If you don't own the site, then at least try to inject the SDK before anyone else and prefer not async

    I also reported the same to FB. They told not to call init separately, pass init params directly in the rule. I've attached the code that I use:

    if (!document.getElementById("fb-root")) {
          // create div required for fb
          const fbDiv = document.createElement("div");
          fbDiv.id = "fb-root";
          document.body.appendChild(fbDiv);
          // Run any script after sdk is loaded
          window.fbAsyncInit = () => {
            //
          };
          // inject sdk.js
          (function(d, script) {
            script = d.createElement("script");
            script.type = "text/javascript";
            script.async = true;
            script.src =
              "https://connect.facebook.net/en_GB/sdk.js#xfbml=1&version=v3.2&appId=" +
              process.env.REACT_APP_FB_APP_ID +
              "&autoLogAppEvents=1";
            d.getElementsByTagName("head")[0].appendChild(script);
          })(document);
        }
    
    
    0 讨论(0)
  • 2020-12-08 19:03

    I got it working by using all.js instead of sdk.js.
    In your case, it would look like:

    js.src = "//connect.facebook.net/pl_PL/all.js";
    

    instead of

    js.src = "//connect.facebook.net/pl_PL/sdk.js";
    
    0 讨论(0)
  • 2020-12-08 19:04

    This was the only fix that would eliminate the error 100% of the time.

    You can recreate this error by deleting your FB.init. Which confirms that although the sdk.js had been loaded and the FB namespace existed, FB.init hadn't been called by the time we were trying to use FB methods elsewhere in our scripts.

    So we need to ensure that FB.init has been called. I used a similar approach to this answer:

    if (typeof(fbApi) === 'undefined') { fbApi = {}; }
    fbApi = (function () {
    
        var 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  : '<?php echo esc_js( $facebook_app_id ); ?>',
            status : true,
            cookie : true,
            xfbml  : true,
            version: 'v2.0'
          });
    
          fbApiInit = true;
          notifyQ();
        };
    
        return {
            /**
             * Fires callback when FB is initialized and ready for api calls.
             */
            'ready': ready
        };
    
    })();
    
            (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'));
    

    Then, elsewhere, any reference to FB can be made like this:

            fbApi.ready(function() {
              FB.XFBML.parse($("#fb-comments"));
            });
    
    0 讨论(0)
  • 2020-12-08 19:05

    We use our own API that does this:

       _loadFacebookApi: function(callback) {
            logger.info('_loadFacebookApi');
    
            (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 = "https://connect.facebook.net/en_US/sdk.js";
    
    
            }(document, 'script', 'facebook-jssdk'));
    
            var fbScript = window.document.getElementById('facebook-jssdk');
    
            fbScript.onload = fbScript.onreadystatechange = (function() {
    
                logger.info('fbScript onLoad');
    
                window.FB.init({
                    version: 'v2.1',
                    appId: '',
                    channelUrl: '/fbchannel.html',
                    status: false,
                    cookie: true,
                    xfbml: true,
                    logging: true,
                    oath: true
                });
    
                this.dispatch(constants.FACEBOOK_INIT_SUCCESS);
    
                if(callback){
                    callback();
                }
    
            }.bind(this));
    
        }
    
    0 讨论(0)
  • 2020-12-08 19:06

    In my case it was an api version problem, as suggested by the error message.

    Let the version loaded in the FB script tag match the one in your FB initialization script, by specifing the same when loading the sdk (in the hash), for instance for version 4.0:

    <script src="https://connect.facebook.net/en_US/sdk.js#xfbml=1&version=v4.0"></script>
    

    and in your script like:

    window.fbAsyncInit = function() {
        FB.init({
            appId: XXX,
            autoLogAppEvents: true,
            xfbml: true,
            version: 'v4.0' //<------------- same version
        });
    };
    
    0 讨论(0)
提交回复
热议问题