web-dev-qa-db-ja.com

FBの初期化関数が誤ったバージョンエラーを表示する

Facebook JS SDKを使用していますが、今日は新しいアプリを作成しました。すべてが正しく構成されています。次のようなinit関数を使用します。

window.fbAsyncInit = function() {
    FB.init({
      appId      : 'xxxx', // App ID
      status     : false, 
      version:  'v2.0',
      cookie     : true, 
      xfbml      : false  // parse XFBML
    });
};

    (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/pl_PL/sdk.js";
         fjs.parentNode.insertBefore(js, fjs);
       }(document, 'script', 'facebook-jssdk'));

しかし、「Uncaught Error:init not called with valid version」というエラーが発生しました:2.1、2.2、まだ運のない他のバージョンも試していました。ここで何が間違っていますか?

49
abiku

**免責事項-これは単なる推測です。私の問題を解決したようです。


最近のプロジェクトでこの問題が発生しました。これは遅延の問題だと思います。 Facebook SDKでは、ページに_<div id="fb-root"></div>_が必要です。これは、開始bodyタグの後の最初のものでなければなりません。この後、初期化コードが表示される場合があります。

私にとって、この問題は一貫していませんでした。たまにバグが見られることもあれば、見られないこともありました。したがって、遅延の問題であるとの私の結論。 SDKが_fb-root_を見つけられない場合、作成する必要があります。ここで、レイテンシーの問題が存在すると信じています。

これを開始bodyタグの直後、ただしFB.init({});の前に追加してみてください。

_<div id="fb-root"></div>
_

これは私にとって問題を解決したようで、うまくいけば他の人にも役立つでしょう。 v1.0 documentation は_fb-root_の理由について説明していますが、v2.0のドキュメントではアイテムが記載されていません。それ。

33
Matt Wagner

Sdk.jsの代わりにall.jsを使用して機能しました。
あなたの場合、次のようになります。

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

の代わりに

js.src = "//connect.facebook.net/pl_PL/sdk.js";
25
n_y

追加 &version=v2.0からjs.srcへ、次のように:

(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#xfbml=1&version=v2.0";
  fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
11
Mythical Fish

この問題はしばらく悩みました。バージョン番号の変更やfb-rootの移動/削除など、ここに挙げたアイデアの多くを試しました。

最後にうまく機能しているのは、window.fbAsyncInit関数全体を削除し、sdk.jsのハッシュでinitプロパティを指定することです。例えば:

<script type="text/javascript">
    (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#version=v2.2&appId=12345&status=true&cookie=true&xfbml=true";
        fjs.parentNode.insertBefore(js, fjs);
    }(document, 'script', 'facebook-jssdk'));
</script>

もちろん、パラメータを省略してデフォルト値を使用することもできます。

このアプローチがどこにも文書化されていないので、自己責任で使用してください。幸いなことに、古いサイトをv1.xからv2.xにアップグレードしていましたが、all.jsを読み込むときにこの手法を使用していました。

5
WimpyProgrammer

私はこれを交換しました

js.src = "//connect.facebook.net/en_US/sdk.js";

これとともに

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

そして働いた:)

5
saadk

これは、エラーを100%除去する唯一の修正でした。

FB.initを削除すると、このエラーを再作成できます。これにより、sdk.jsが読み込まれ、FB名前空間が存在していても、スクリプトの他の場所でFBメソッドを使用しようとしていたときにFB.initが呼び出されなかったことが確認されます。

そのため、FB.initが呼び出されていることを確認する必要があります。これに似たアプローチを使用しました 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'));

そして、他の場所では、FBへの参照は次のように行うことができます。

        fbApi.ready(function() {
          FB.XFBML.parse($("#fb-comments"));
        });
3
StuR

これは私にも大きな矛盾を伴って起こっていました。私の予感がどこかに言ったところ、それはタイミングの問題になるはずです。さらにデバッグすると、「FB.login()」を手動で実行することにより、開発者コンソールでエラーが見つかりました。エラーには、「initは有効なバージョンでは呼び出されませんでした」とありました。

私の場合、//connect.facebook.net/en_US/sdk.jsは、HTMLページのヘッダーおよびwindow.fbAsyncInitはその直後に別のファイルに入ってきました。これはタイミングの問題として私に指摘したので、これら2つのスクリプトタグを交換しました。これで、window.fbAsyncInitを含める前//connect.facebook.net/en_US/sdk.js、問題はなくなりました。これが他の人に役立つことを願っています。

3

このコードを試してください:

setInterval(
function() { FB.api('/me/', 
    function(r) { console.log('response: ', r); })
}, 5000);

情報を取得しようとすると、fbがまだ初期化されていないことに気付きました。

初期化コードを次の末尾に追加して修正しました。

FB.getLoginStatus(function(response) { init(); });
1
Tahimoto

シングルページアプリケーションの場合(私の場合はReact)

単一ページのアプリケーションでは、コードを実行する順序をあまり制御できません。コードを呼び出すまでにスクリプトが読み込まれることもあれば、読み込まれないこともあります。

Facebookスクリプトが既に読み込まれているかどうかに関係なく動作させるために、コードの実行時にFBグローバル変数が既に定義されているかどうかを確認します。その場合は、通常の初期化を行うだけです。それ以外の場合は、コールバックを提供します。

これは私のコードです:

_export function initializeFacebookSdk() {

  /* Asynchronous flow: if the global 'FB' variable is still undefined,
     then the facebook script hasn't loaded yet, in that case, provide
     a global callback that will be called by the facebook code. If the 
     variable is already present, just call the code right away and forget
     about the callback. */
  if(window.FB === undefined) {
    console.log('FB undefined -> provide callback');
    window.fbAsyncInit = function() {
      initialize();
    };
  }
  else {
    console.log('FB defined -> call init right away');
    initialize();
  }

  function initialize() {
    window.FB.init({
      appId      : '492331311256888',
      cookie     : true,
      xfbml      : true,
      version    : 'v3.2'
    });    
  }
}
_

私のhtmlファイルでは、facebookで指定されたスクリプトを提供するだけで、コードでは、いつでもどこでもinitializeFacebookSdk()を呼び出すことができます。

_<!DOCTYPE html>
<html lang="en">
  <head>
    <title>My application</title>
  </head>
  <body>    
    <noscript>
      You need to enable JavaScript to run this app.
    </noscript>

    <script>    
      (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";
         fjs.parentNode.insertBefore(js, fjs);
       }(document, 'script', 'facebook-jssdk'));
    </script>

    <div id="root"></div>
  </body>
</html>
_
1
Alexander Derck

ドキュメントの読み込みではなく、ドキュメントの準備ができたスクリプトを読み込むことで、このエラーを解決しました。

たとえば、これにより、約10%の時間にエラーが発生しました。

$(window).load(function(){
  (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'));
});

一方、これは常に機能します:

$(window).ready(function(){
  (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
afessler

初期化後にFB apiを呼び出すときは注意してください。 Initは同期しているように見えますが、window.fbAsyncInitは同期していないため、実行を待つ必要があります。再現する私の例はphonegapブラウザプラットフォームですが、facebookプラグインコードを確認した後、純粋なjavascript環境でも再現できると確信しています。

これはエラーを発生させる私のコードでした:

if (window.config.debug_mode) {
    facebookConnectPlugin.browserInit('xxxxxxxxx', function() {
    });
}
// getLoginStatus is wrong here as window.fbAsyncInit is not yet completed
facebookConnectPlugin.getLoginStatus(function(status) {
    alert('logged: ' + JSON.stringify(status));
}, function(error) {
    alert('error: ' + JSON.stringify(error));
});

修正方法は次のとおりです。

if (window.config.debug_mode) {
    facebookConnectPlugin.browserInit('xxxxxxxxx', function() {
        facebookConnectPlugin.getLoginStatus(function(status) {
            alert('logged: ' + JSON.stringify(status));
        }, function(error) {
            alert('error: ' + JSON.stringify(error));
        });
    });
}

次のコードがブラウザーにスローされると確信していますが、検証する時間はありません。

window.fbAsyncInit = function fbAsyncInit () {
    version = version || 'v2.6'

    FB.init({
        appId: appId,
        xfbml: false,
        version: version
    })
}
// now calling any FB function here will rise this error
1
user732456

URLで_https://_を使用していることを確認してください

_js.src = "https://connect.facebook.net/en_US/sdk.js";
_

私もこれを信じていませんでしたが、Facebookが現在のサンプルコードで持っているものと私が持っているものとの唯一の違いは、URLの_https://_の代わりに_//_です。

Https://に更新すると修正されたようで、エラーを再現できません。

また、コードの別の場所でFBが定義されているかどうかを確認する場合は、if (window.FB)ではなくif (FB)を確認してください。そうしないとエラーが発生します。

_// call after manually adding DOM nodes containing FB widgets
if (window.FB)
{
    window.FB.XFBML.parse()
}
_

TypeScriptを使用している場合、次のようなものを追加する必要があります。

_interface Window
{
    FB: IFacebook;
}

interface IFacebook
{
    XFBML: any;
    ui: any;
    getLoginStatus(callback: (response: { status: string }) => any);
    login(callback: (response) => any, options: any);
    logout(callback: () => any);
    Event: any;
    api(url: string, callback: (response: any) => any);
}
_
0
Simon_Weaver

単一のインクルード— Facebook JavaScript APIがページに複数回含まれないようにしてください。

(これは私の問題でした)

0
redolent

執筆中の記事に簡単なFacebook投稿を埋め込むと、同じ問題が発生しました。

<div id="fb-root"></div><script>(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#xfbml=1&amp;version=v2.3";  fjs.parentNode.insertBefore(js, fjs);}(document, 'script', 'facebook-jssdk'));</script><div class="fb-post" data-href="https://www.facebook.com/feyenoord/posts/10153224326681816:0" data-width="500"><div class="fb-xfbml-parse-ignore"><blockquote cite="https://www.facebook.com/feyenoord/posts/10153224326681816:0"><p>Een teleurstellende middag in De Kuip. Ook ADO Den Haag bleek vanmiddag te sterk voor Feyenoord. http://bit.ly/1UA3ZxZADO Den Haag too strong for Feyenoord. http://bit.ly/1UA6rEN</p>Posted by <a href="https://www.facebook.com/feyenoord/">Feyenoord Rotterdam</a> on&nbsp;<a href="https://www.facebook.com/feyenoord/posts/10153224326681816:0">Sunday, January 31, 2016</a></blockquote></div></div>

Facebook sdk.jsをデバッグしたとき、.getVersionが「未定義」を返し、ウィジェットをレンダリングしていないことがわかりました。

Facebookは、&amp;を読み込むときに、&の代わりにsdk.jsで区切られたクエリパラメーターの受け渡しを処理できないようです。検証のため、コードを&amp;に変更しました。

Works:        js.src = "//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.3";
Doesn't Work: js.src = "//connect.facebook.net/en_US/sdk.js#xfbml=1&amp;version=v2.3";

Facebook sdk debug getVersion

0
JeroenVdb

Fb-pageプラグインがあるページ(Edge Browser)にリダイレクトするたびにエラーが発生しました。

ページを更新すると機能します。ハイパーリンクを介してアクセスすると、エラーがスローされます。

sdk.js?d=" + new Date().toISOString();をスクリプトに追加して修正しました。

(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?d=" + new Date().toISOString();
        fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
0
adrianvlupu

これを行う独自のAPIを使用します。

   _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
4m1r

私は同じ問題を抱えていた、そして私は根本的な原因を見つけたと思う!

根本的な原因

私の場合、FB SDKを顧客のWebサイトに動的に注入していました。ただし、一部のお客様には、他のプラグインを介してFB SDKが既に追加されています。これらのプラグインには異なるアプリIDとバージョンがあります。

だから、いくつかのプラグインはレイテンシーに応じてinitを呼び出します

解決

あなたがSDKを注入しているサイトの所有者である場合、他のプラグインがFB SDKを注入し、init異なるバージョンとアプリIDを呼び出していないことを確認してください

サイトを所有していない場合は、少なくとも他の誰かの前にSDKを挿入してnot async

私もFBに同じことを報告しました。彼らは、initを個別に呼び出さないで、ルールにinit paramsを直接渡すように指示しました。私が使用するコードを添付しました:

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
Gijo Varghese

Cordova-plugin-facebook4プラグインを使用しています。これはカスタムエラーメッセージであり、facebook api関数が呼び出されたときにinitが終了していないことを意味します。プラグインはsetTimeoutを使用してwaitForInitializeを提供しないため、apiメソッドを再試行することが最善策です。

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. */
0
Warren Parad