Detect that a Javascript file did not load (Facebook's JS file) - javascript

When a user comes to our site, if they've logged into our Facebook app, we want to show them the "logged-in" view for the app showFacebook(). Otherwise, we want to display an option to login to the app or login to our site with a local account showLogin().
window.fbAsyncInit = function() {
FB.init({
appId : <cfif cgi.SERVER_NAME CONTAINS "dev">'460582120708297'<cfelse>'1422691834609812'</cfif>,
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
FB.Event.subscribe('auth.authResponseChange', function(response) {
// Handle the results of logging in
if (response.status === 'connected') {
showFacebook();
}
else {
showLogin();
}
});
// Check if the user is already logged into the Facebook app
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
showFacebook();
} else {
showLogin();
}
});
};
// Load the SDK asynchronously
(function(d){
var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
}(document));
This works great most of the time. But, sometimes, neither showFacebook() nor showLogin() are firing. My guess is that these are users who are at work or at school, and their network admins have blocked Facebook.
How can I detect that the Facebook JS file (http://connect.facebook.net/en_US/all.js) is not loading?

Check if window.FB is defined. If not, the library didn't load.
if (window.FB) {
// go for it
}

I went with a variation on Doge's response:
$(document).ready(function(e) {
// Show the login without the Facebook button if Facebook doesn't load in 5 seconds
setTimeout(function(){
if(!window.FB){
$("#facebook_login_area").hide();
showLogin();
}
},5000);
});
I give the asynchronous call from Facebook 5 seconds to load. If it hasn't loaded in that time, I display my showLogin() without the option to login to the Facebook app.

Related

FB.getLoginStatus doesn't fire callback in native Android browser

This problem had just showed up in my app when I view it on the native Android browser in ICS and Jellybean. All works as intended on desktop browsers and even Chrom for Android. This has occurred in the past few days, was working fine last week, and nothing in the code has changed.
The following code, which is a simplified version of what my app does, is essentially what I'm doing to initiate a connection to FB. I'm expecting the alerts in A and B, or A and C will pop, but instead, nothing happens.
window.fbAsyncInit = function () {
FB.init({
appId: '', // App ID
channelUrl: 'http://localhost/fb/channel', // Channel File
status: true, // check login status
cookie: true, // enable cookies to allow the server to access the session
xfbml: true // parse XFBML
});
FB.getLoginStatus(function (response) {
alert("any response"); //<-- A
if (response.status == 'connected') {
alert("connected"); // <-- B
} else {
//somehow user was not already signed in or did not fully authorize
FB.login(function (response) {
if (response.authResponse) {
alert("connected"); // <-- C
} else {
console.log('User cancelled login or did not fully authorize.');
}
});
}
});
};
// Load the SDK Asynchronously
(function (d) {
var js, id = 'facebook-jssdk',
ref = d.getElementsByTagName('script')[0];
if (d.getElementById(id)) {
return;
}
js = d.createElement('script');
js.id = id;
js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
}(document));
Anyone experiencing that same and have a workaround or solution?

FB.Event.subscribe not working

I am working on a website and wanted to give my users an option to log-in using facebook.
I am successful at logging in but events are not working for me.
Whenever i logged in, the function "login" was not called.....I have tried assigning this login function to other button for checking it manually, the alert worked but it didnt get any response.
Here my Code:
<div id="fb-root"></div>
<script type="text/javascript">
window.fbAsyncInit = function() {
FB.init({appId: MY_APP_ID, status: true, cookie: true, xfbml: true});
FB.Event.subscribe('auth.login', function(response) {
login();
});
};
function login(){
FB.api('/me', function(response) {
alert('You have successfully logged in, '+response.name+"!");
});
}
(function() {
var e = document.createElement('script');
e.type = 'text/javascript';
e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
e.async = true;
document.getElementById('fb-root').appendChild(e);
}()); </script>
<fb:login-button autologoutlink='true'
perms='email,user_birthday,status_update,publish_stream'></fb:login-button>
This is the facebook application setting:
Have you tried loading the all.js script in the <head> instead of #fb-root? Use the following:
(function(d){
var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/es_LA/all.js";
d.getElementsByTagName('head')[0].appendChild(js);
}(document));
instead of:
(function() {
var e = document.createElement('script');
e.type = 'text/javascript';
e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
e.async = true;
document.getElementById('fb-root').appendChild(e);
}());
[EDIT: updated sample]
The SDK inserts elements into fb-root which expect to be positioned relative
to the body or relative to an element close to the top of the page.
Which might replacing the SDK source as well.
resource: Facebook Javascript SDK.
--
can you try to subscribe to other event and see if its work
FB.Event.subscribe('auth.statusChange', function(response) {
// do something with response
});
From Facebook documentation (try subscribing this instead)
auth.authResponseChange
This event is fired for any auth related change as they all affect the session: login, logout, session refresh. Sessions are refreshed over time as long as the user is active with your app.
auth.statusChange
Typically you will want to use the auth.authResponseChange event. But in rare cases, you want to distinguish between these three states:
1. Connected
2. Logged into Facebook but not connected with your application
3. Not logged into Facebook at all.
Scenario 1 (New User)
Facebook Login Button's Text: "Login"
User State: User not connected
Now user clicks on login and completes the login flow.
Button's text changes to "Log Out" and this is the only time when'auth.login' triggers.
FB.Event.subscribe('auth.login', function (response) {
// do something with response
if (response.status === 'connected') {
// user connected
FB.api('/me', function (response) {
alert(response.name + " " + response.id);
});
}
});
Scenario 2 (Existing User)
If a user who is logged in to Facebook and has already authorized your app visits your app then the user automatically get's connected and Login Button's text is "Log Out".
In this case add the following code into the fbAsyncInit function:
FB.getLoginStatus(function (response) {
if (response.status === 'connected') {
// connected
alert(response.name + " " + response.id);
}
});
FB.getLoginStatus is called everytime the page refreshes but you can also call it anytime in your app by embedding it into a javascript function.

Facebook API - Detect if session is active OR NOT active

I'm sure I'm simply overlooking something in the Facebook API docs. Basically, after I've loaded the FB Graph, I need to know if the session is active... I cannot simply assume they're logged out and simply re-render if they're logged in once the 'auth.statusChange' event is triggered. I need to know right off the bat.
Below is the code that I've used. Most importantly the FB.getLoginStatus/getAuthResponse/getAccessToken don't work like I'd expect; essentially where it indicates, when invoked, whether they're logged in or out.
(function(d) {
// Create fb-root
var fb_root = document.createElement('div');
fb_root.id = "fb-root";
document.getElementsByTagName('body')[0].appendChild( fb_root );
// Load FB Async
var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
// App config-data
var config = {
appId : XXXX,
cookie: true,
status: true,
frictionlessRequests: true
};
window.fbAsyncInit = function() {
// This won't work.
// I can't assume they're logged out and rely on this to tell me they're logged in.
FB.Event.subscribe('auth.statusChange', function(response) {});
// Init
FB.init(config);
// These do not inidicate if the user is logged out :(
FB.getLoginStatus(function(response) { });
FB.getAuthResponse(function(response) { });
FB.getAccessToken(function(response) { });
};
}(document));
Any help is much appreciated. :)
Thanks for the help, but I found the answer on another post: https://stackoverflow.com/a/7765144/560686
Apparently, when you're still in Sandbox mode FB.getLoginStatus() will fire the callback only when they're logged in, but not when they're logged out. To get this to work, I had to Disable the Sandbox mode. :)

FB.getLoginStatus Requires Page Refresh before Firing

I have a Facebook Page Tab App that is not loading correctly until after the page is refreshed. I have been trying to solve this problem for over a week, and am reaching my wits end.
Here is the code:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script src="https:////connect.facebook.net/en_US/all.js"></script>
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function() {
FB.init({
appId : '***************', // App ID
channelURL : '//www.********.com/**********/channel.html', // Channel File
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
});
// Additional initialization code here
};
// Load the SDK Asynchronously
(function(d){
var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
d.getElementsByTagName('head')[0].appendChild(js);
}(document));
</script>
<script type="text/javascript">
$(document).ready(function(){
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
//User Logged In
}
else if (response.status === 'not_authorized') {
//Log User Into App
}
else
{
top.location = "http://www.facebook.com";
}
});
});
</script>
Like I said, if add something like alert("Test") immediately after FB.getLoginStatus(function(response) { it doesn't pop up on the first page load, but does after the page is refreshed.
Can someone please help point me in the right direction?
Thanks,
Fred
First of all you are loading the SDK both Synchronously and Asynchronously. Remove the synchronous line. Then all your FB related lines should be within the window.fbAsyncInit. You can't subscribe to events before the sdk is fully loaded.
You can try it this way if you haven't already
FB.getLoginStatus(function(response) {
if (response.authResponse) {
// logged in and connected user, someone you know
} else {
// no user session available, someone you dont know
}
});

Is there a way to detect if the Facebook Javascript SDK loaded successfully?

I use Facebook as the membership system of my website. It uses the code to generate a login control, allowing users to login via their facebook account. It's essentially one click if they're already a member, 2 if they're not (for granting permissions).
I got a problem though... feedback is suggesting the login button isn't always loading correctly. Instead of loading the facebook login control, it simply states (in text) "login via facebook" - which is what the login button would say if the control loaded successfully.
Testing shows that is what happens when the facebook javascript SDK fails to load completely (for whatever reason). I've seen instances where a # in the url prevents the SDK from loading.
To better support this issue, how would I go about detecting if the facebook javascript SDK loaded, and is ready? That way, if it fails, I can leave some sort of note for the user.
Here's how it's currently added to the page:
<script>
window.fbAsyncInit = function () {
FB.init({
appId: '***************',
status: true,
cookie: true,
xfbml: true
});
FB.Event.subscribe('auth.login', function (response) {
window.location.reload();
});
};
(function () {
var e = document.createElement('script'); e.async = true;
e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
document.getElementById('fb-root').appendChild(e);
} ());
</script>
You should load the Javascript Library Asynchronously and put all your FB related functions inside the window.fbAsyncInit method:
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function() {
FB.init({
appId : 'YOUR_APP_ID', // App ID
channelUrl : '//WWW.YOUR_DOMAIN.COM/channel.html', // Channel File
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
// Additional initialization code here
};
// Load the SDK Asynchronously
(function(d){
var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
}(document));
</script>
This code loads the SDK asynchronously so it does not block loading
other elements of your page. This is particularly important to ensure
fast page loads for users and SEO robots.
The URLs in the above code are protocol relative. This lets the
browser to load the SDK over the same protocol (HTTP or HTTPS) as the
containing page, which will prevent "Insecure Content" warnings.
The function assigned to window.fbAsyncInit is run as soon as the SDK
is loaded. Any code that you want to run after the SDK is loaded
should be placed within this function and after the call to FB.init.
For example, this is where you would test the logged in status of the
user or subscribe to any Facebook events in which your application is
interested.
A quick example is the following:
<div id="fb-root"></div>
<script>
var isLoaded = false;
window.fbAsyncInit = function() {
FB.init({
appId : 'YOUR_APP_ID', // App ID
channelUrl : '//WWW.YOUR_DOMAIN.COM/channel.html', // Channel File
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
isLoaded = true;
// Additional initialization code here
};
function checkIfLoaded() {
if(isLoaded) console.log("LOADED!");
else console.log("NOT YET!");
return false;
}
// Load the SDK Asynchronously
(function(d){
var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
}(document));
</script>
Check
(Just clicked the check link a couple of times)
Please note that you can still construct the Login Link server-side and WITHOUT JavaScript. Example using the PHP-SDK:
$loginUrl = $facebook->getLoginUrl();
...
...
<a href="<?php echo $loginUrl; ?>">
<img src="http://static.ak.fbcdn.net/rsrc.php/zB6N8/hash/4li2k73z.gif">
</a>
Trigger an event when the SDK is loaded:
window.fbAsyncInit = function() {
FB.init({appId: "#{KeyManager.facebook_app_id}", status: true, cookie: true, xfbml: true});
jQuery('#fb-root').trigger('facebook:init');
};
And listen for the event like this:
$("#fb-root").bind("facebook:init", function() {
..
});
If you are using jQuery (and you have loaded jQuery prior to the FB initialization) you can use a Deferred to run additional initialization.
<script>
window.fbLoaded = $.Deferred();
window.fbAsyncInit = function() {
FB.init({
appId : '----------',
xfbml : true,
status : true,
version : 'v2.7'
});
window.fbLoaded.resolve();
};
(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'));
</script>
Then elsewhere (in a JS file) you can do this (in fact the key of this method is you can put this in as many places as you want and they will all get triggered):
window.fbLoaded.done(function () { alert('FB initialized'); });
Note: If the initialization completes BEFORE you add the done event it will fire immediately (that is how Deferreds work). So you can put it wherever you want.
Be sure to test what you want the behavior to be if the API is never initializaed (just comment out the (function(d,s,id)... part
Just look for FB object after loading FB JS SDK sync/async as given:
if (typeof FB !== 'undefined') {
alert("FB JS API is available now");
} else {alert("do something...")}
That's a enough check to call any Facebook JS API related method safely.
Promise-based version, for modern browsers
// Load Facebook JS SDK
(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#xfbml=1&version=v2.11';
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
// Create a new promise, set to resolve using the global function `fbAsyncInit`,
// which the Facebook JS SDK will call once it's ready.
new Promise((resolve, reject) => {
window.fbAsyncInit = resolve;
}).then(() => {
// ... your code here ...
});
What globals does this JS file introduce?
Let's say it creates a
var FaceBook = function() {//make friends! Or whatever...}
You can test for if (FaceBook) and go from there.
It seems likely that they give you some sort of load event for when their framework is booted up, so to speak.
According to this page http://www.techsirius.com/2014/04/detect-social-SDK-didnt-load.html
$(window).load(function(){
if(typeof window.FB == 'undefined'){
alert('Facebook SDK is unable to load, display some alternative content for visitor');
}
else{
alert('Facebook is working just fine');
}
});
Load the script dynamically (add a script tag from js) and check for error / success events.
var FB;
jQuery.fbInit = function(app_id) {
window.fbAsyncInit = function() {
FB.init({
appId : app_id,
status : true,
channelUrl: '#',
cookie : true,
xfbml : true
});
FB = FB;
getLoginStatus();
};
// Load the SDK Asynchronously
(function(d){
var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/it_IT/all.js";
d.getElementsByTagName('head')[0].appendChild(js);
}(document));
$('<div />').attr('id','fb-root').appendTo('body');
};
/**
* https://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus/
*/
function getLoginStatus() {
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
$('#fb-root').trigger('facebook:init',[response]);
} else if (response.status === 'not_authorized') {
$('#fb-root').trigger('facebook:init',[response]);
} else {
$('#fb-root').trigger('facebook:init',[response]);
}
});
}
If you want check the status from another javascript (with the suggestion of #Leo Romanovsky )
$("#fb-root").on("facebook:init", function(event, response) {
if(response.status === 'connected') {
alert("logged with FB")
}else{
alert("No Logged with FB")
}
});
I use this from few days :
var isLoaded = false;
$(document).on('DOMSubtreeModified', function () {
if ($('#fb-root').length && !isLoaded) {
isLoaded = true;
// ...
}
});
What do you think ?
As stated in other answers; with thanks to #ifaour & #Leo Romanovsky; the best way to detect if the SDK is loaded successully is to trigger an event when the fbAsyncInit is called.
If the event is captured then the SDK is loaded. The code below shows how this could be achieved:
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function() {
FB.init({
appId : 'YOUR_APP_ID', // App ID
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
// Fire an event when the FB library asynchronously is loaded
$("#fb-root").trigger("facebook:init");
// Additional initialization code here
};
// 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"));
</script>
// Somewhere else in the code
$(document).ready(function () {
$("#fb-root").bind("facebook:init", function () {
console.log("The event is fired FB SDK object is ready to be used.");
});
});
In the event that the event is not fired you could add a timer to check if FB object is 'undefined' and show the appropriate message.
Note 1: Downside there could a slight delay till this event is fired.
Note 2: "feedback is suggesting the login button isn't always loading correctly". I know that FFv49 private browsing blocks the call to fb.

Categories

Resources