Facebook API - Detect if session is active OR NOT active - javascript

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. :)

Related

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

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.

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?

Scriptaculous dom:loaded working only "sometimes"?

So basically, I'm working on a Facebook login flow for my website. It's fairly basic, but giving me some problems. The issue appears that the click observer is only working some of the time. A hard refresh will typically fix the problem. The following is my JS code used to get into it...
function fb_login(login_destination)
{
FB.login(function(response) {
if (response.authResponse) {
var fb_auth_token = response.authResponse.accessToken;
var fb_user_id = response.authResponse.userID;
var url = '/login/ajax/fb_login.php?fb_auth_token=' + fb_auth_token + '&fb_user_id=' + fb_user_id + '&fb_login=' + login_destination;
window.location = url;
}
}, {scope: 'email,user_about_me'});
}
document.observe("dom:loaded", load_fb);
function load_fb()
{
window.fbAsyncInit = function(){
FB.init({
appId : 'ID'
status : true,
cookie : true,
xfbml : true,
oauth : true
});
};
$('fb_connect').observe('click',function(event){
var login_destination = $('fb_connect').getAttribute('dest');
fb_login(login_destination);
});
}
The only symptom appears to be that it simply will not respond to clicks on certain page loads. The ID I'm using is tied directly to the image itself. I'm curious if anyone has ran into this and knows how to fix it. Thanks.
I've run into this before. I ended up using timer to start the initialization script as a backup. The function sets a variable and exits if it has already run. Ugly, but effective.
So, I wound up fixing this. The code effectively got changed to this....
function load_fb()
{
var d = document;
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);
Basically I'm just now waiting to bring in the FB JS SDK until after the page load (reference earlier code for this to make sense). It doesn't have anything to do with scriptaculous.

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