calling FB.login() in FB.logout() callback function - javascript

I have to check the FB user is the user who logged in my app,
my idea is that call login() in logout() callback function using javascript
FB.getLoginStatus(function(response){
if(response.authResponse){
FB.logout(function(r1){
FB.login(function(r2){
...
...
...
},{scope:"..., ..., ..."});
});
}
});
It can logout successfully. But after I log in, the log in dialog doesn't close.
I've try to set auth_type to re-authenticate, but reauth dialog cannot logout if the FB user isn't correctly.
I'm using URL to logout in some cases. but not suitable for all.
Anyone has idea for login function in the logout callback function?

Related

prevent facebook js sdk from calling login callback

I have a Facebook login button:
<fb:login-button scope="email,user_birthday">Login with Facebook</fb:login-button>
and this JS:
window.fbAsyncInit = function() {
FB.init({
appId: 'APP_ID_HERE',
cookie: true,
xfbml: true,
oauth: true
});
FB.Event.subscribe('auth.login', function(response) {
window.location.reload();
});
};
My issue is that any page that contains this code always reloads once. It's because the login callback above is called (if the user is logged in to a Facebook account) even if the user has not yet clicked on the Login button above. Is this normal behavior? If not, how do I prevent the login callback from being called?
This event fires each time the SDK detects that the state changes from unknown/not_connected to connected.
It sounds like you want to actually provide a callback handler on the login button via onlogin
One solution: You could use the PHP sdk to check for the user status, and only if the user is NOT logged in, create the JavaScript part where you subscribe to auth.login.

FB.getLoginStatus doesn't work in Chrome even sandbox disable

I follow railscast to add "sign in with Facebook" feature in my site, there is no problem to login. But when try to logout, it seems that FB.getLoginStatus never got fire even when I disable Sandbox Mode in facebook developer app settings (as suggested in some other discussion):
(function() {
jQuery(function() {
$('body').prepend('<div id="fb-root"></div>');
return $.ajax({
url: "" + window.location.protocol + "//connect.facebook.net/en_US/all.js",
dataType: 'script',
cache: true
});
});
window.fbAsyncInit = function() {
FB.init({
appId: 'xxxxxomittedxxxxx',
cookie: true,
status: true,
xfbml: true,
oauth: true
});
$('#sign_in').click(function(e) {
e.preventDefault();
return FB.login(function(response) {
if (response.authResponse) {
return window.location = '/auth/facebook/callback';
}
});
});
return $('#sign_out').click(function(e) {
FB.getLoginStatus(function(response) {
if (response.authResponse) {
return FB.logout(response.authResponse);
}
});
return true;
});
};
}).call(this);
The reason I know the FB.getLoginStatus never get in (or doesn't work) is I replace the body with:
FB.getLoginStatus(function(response) {
return alert("I am here!");
});
and I cannot see my alert while "sign_out" click.
I am running both Chrome and Firefox having the same behaviour. Could anybody help to spot what am I missing? Thanks a lot.
Let me describe more specific about the "behaviour" I encountered:
sign in with Facebook from mysite.com the first time a Facebook login window will popup and ask for email and password, and I can sign in to my site perfectly ok and work as expected
then I click on sign_out button from mysite.com/users/1, it looks like it sign out ok.
then sign in with Facebook from mysite.com again, now it won't popup the Facebook login window anymore and login to mysite.com/users/1 directly without asking email and password!
if I open another browser window and go to facebook.com and logout from there, then when I sign in with Facebook from mysite.com, it will popup a Facebook login window now and ask for my email and password.
I would like my site to behave: "when logout from mysite.com/users/n and sign in with Facebook again from mysite.com, the Facebook login window shall popup"
Anyone could be of help? Thanks a lot.
EDIT:
Further investigation found the "root" cause might be still: the sign out is under the different route (or page) of the sign in route and FB.getLoginStatus just cannot be fire under the mysite.com/signout. The error message from firebug indicates that "Given URL is not allowed by the Application configuration.: One or more of the given URLs is not allowed by the App's settings. It must match the Website URL or Canvas URL, or the domain must be a subdomain of one of the App's domains."
To proof it is the route issue, I put a sign out link in the same route (page) as sign in route which is the root route mysite.com as specified in the "Website with Facebook Login", everything works and can logout as expected:
<%= link_to "sign out facebook", "#" , id: "sign_out" %>
by the way the sign_out js is revised to get rid of FB.logout(response.authResponse) uncaught [object Object] error, because FB.logout expects function as parameter:
return $('#sign_out').click(function(e) {
FB.getLoginStatus(function(response) {
if (response.authResponse) {
FB.logout();
}
}, true);
});
};
So, the bottom line: FB.getLoginStatus might still have a bug which cannot handle the call from a different route than sign in route. (I tested with Chrome, Firefox and Safari and all behave the same but not true for IE10. Somehow IE10 works even sign out at different route.)
Any comment from people who have similar problem? Please advise. Thank you very much in advance.
Try adding true as second parameter to getLoginStatus, as stated in FB dev doc:
FB.getLoginStatus(function(response) {
// this will be called when the roundtrip to Facebook has completed
}, true);
This should avoid caching.
Another option is to subscribe to events:
FB.Event.subscribe('auth.login', function(response) {
// do something with response
});
All from here
Comment if you have questions.
EDIT:
I modified your script a little bit, removed unneeded code parts. You had too many returns that are not needed. I tried sign out within this modified script, it works as you need it.
Events subscription is for check purposes.
<head>
<title>Exam entry</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
</head>
<body>
<div id="fb-root"></div>
<input type="button" value="Sign in" id="sign_in" />
<input type="button" value="Sign out" id="sign_out" />
<script type="text/javascript">
window.fbAsyncInit = function () {
FB.init({
appId: '586844044669652',
cookie: true,
status: true,
xfbml: true
});
// Here we subscribe to the auth.authResponseChange JavaScript event. This event is fired
// for any authentication related change, such as login, logout or session refresh. This means that
// whenever someone who was previously logged out tries to log in again, the correct case below
// will be handled.
FB.Event.subscribe('auth.authResponseChange', function (response) {
// Here we specify what we do with the response anytime this event occurs.
if (response.status === 'connected') {
// The response object is returned with a status field that lets the app know the current
// login status of the person. In this case, we're handling the situation where they
// have logged in to the app.
testAPI();
} /*else if (response.status === 'not_authorized') {
// In this case, the person is logged into Facebook, but not into the app, so we call
// FB.login() to prompt them to do so.
// In real-life usage, you wouldn't want to immediately prompt someone to login
// like this, for two reasons:
// (1) JavaScript created popup windows are blocked by most browsers unless they
// result from direct interaction from people using the app (such as a mouse click)
// (2) it is a bad experience to be continually prompted to login upon page load.
FB.login();
} else {
// In this case, the person is not logged into Facebook, so we call the login()
// function to prompt them to do so. Note that at this stage there is no indication
// of whether they are logged into the app. If they aren't then they'll see the Login
// dialog right after they log in to Facebook.
// The same caveats as above apply to the FB.login() call here.
FB.login();
}*/
});
$('#sign_in').click(function (e) {
e.preventDefault();
FB.login(function (response) {
if (response.authResponse) {
//return window.location = '/auth/facebook/callback';
}
});
});
$('#sign_out').click(function (e) {
FB.logout(function (response) {
console.log("Here logout response", response);
});
});
};
// Here we run a very simple test of the Graph API after login is successful.
// This testAPI() function is only called in those cases.
function testAPI() {
console.log('Welcome! Fetching your information.... ');
FB.api('/me', function (response) {
console.log('Good to see you, ' + response.name + '.');
});
}
// 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>
</body>

Facebook Javascript API sending two requests

In my application I have a function like this one:
getProfile = function() {
FB.api('/me', function(response) {
console.log(response);
});
return false;
};
Which requests the "me" object from the Facebook Graph API over JavaScript, and it works as expected when I attach it to the onClick event of a regular link or call it from the console directly, but when I try to call it from the Facebook log in button:
<fb:login-button onlogin="getProfile()">
Get Profile
</fb:login-button>
I get the expected response only if I am logged out of Facebook and subsequently log in through the dialog; if I click the button while I'm already logged in, I get this:
And if I push the response to the browser:
getProfile = function() {
FB.api('/me', function(response) {
console.log(response);
var
profile = document.getElementById('profile'),
p = document.createElement('p');
p.innerHTML = response.first_name;
profile.appendChild(p);
});
return false;
};
Of course I get two paragraphs with my name in them.
Can anyone spot what I'm doing wrong? So far my Googling has me convinced that this is related to the way the SDK handles log in events (firing on every page load) but I can't figure out how I'm supposed to account for that in the application code.
I believe the onlogin event fires when you load the page because you are logged into Facebook. Then, when your user clicks the button, it also triggers the event. If you're not logged in in the first place, then the onlogin event doesn't fire on load.
UPDATE: to avoid this, simply don't hook the getProfile to the onlogin event except inside an if statement based on the FB.getLoginStatus method http://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus/ Simply put, if you're logged in, don't attach an onlogin event, otherwise do an FB.Event.subscribe http://developers.facebook.com/docs/reference/javascript/FB.Event.subscribe/ on the onlogin event and your method will run whenever the user logs in through your XFBML-generated login button.
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
//print the response data into the paragraph here
} else if (response.status === 'not_authorized') {
// the user is logged in to Facebook,
// but has not authenticated your app
FB.event.subscribe( 'auth.login', function(){
getProfile();
});
} else {
// the user isn't logged in to Facebook.
}
});

FB.INIT not forcing login even with status:true js sdk

My app allows users to send requests using Facebook Requests Dialogue.
I run the init as follow:
<div id="fb-root"></div>
<script src="http://connect.facebook.net/en_US/all.js"></script>
<script>
FB.init({
appId: '193078857407882',
status: true,
cookie: true,
xfbml: false,
});
</script>
From what I understand in the documentation the 'status: true' is supposed to check if the user is logged in to facebook.
However in my app when the user is not logged in it just shows the following error message:
An error occurred with hbg. Please try again later.
How can I force the application to check if the user is logged in and if not to log in?
Rails 3.0.7, Ruby 1.9.2, Js SDK
According to the Facebook docs for FB.getLoginStatus, if you want to receive the response from passing status: true to FB.init, then you need to subscribe to the auth.statusChange event:
While you can call FB.getLoginStatus any time (for example, when the
user tries to take a social action), most social apps need to know the
user's status as soon as possible after the page loads. In this case,
rather than calling FB.getLoginStatus explicitly, its possible to
check the user's status by setting the status: true parameter with you
call FB.init.
To receive the response of this call, you must subscribe to the
auth.statusChange event. The response object passed by this event is
identical to that which would be returned by calling FB.getLoginStatus
explicitly.
So in your code you would do something like
FB.Event.subscribe('auth.authResponseChange', function(response) {
alert('The status of the session is: ' + response.status);
});
Except you would subscribe to auth.statusChange instead. Note, however, that according to the FB.Event.subscribe docs:
auth.statusChange() does not have a 'status' field.
You can check login status by calling FB.getLoginStatus
FB.getLoginStatus(function(response) {
if (response.authResponse) {
// logged in and connected user
} else {
FB.login(function(res) {
if (res.authResponse) {
// user logged in
} else {
// user cancelled login
}
});
}
});

Confused by nature of JS SDK Facebook Events

I'm having a bit of trouble designing the user login/logout mechanism of my website that works with facebook.
The behavior of certain facebook events seems counter-intuitive:
'auth.login' fires on every page load when the user is logged in.
FB.getLoginStatus() fires on every page load, as I would expect
'auth.logout' fires only when the user actually logs out, and unlike 'auth.login,' auth.logout does not fire on every page load when the user is not logged in.
I want to build a system that detects whether or not the users session thinks that user is logged into facebook. If the user's session is set to believe they're logged into facebook, but they're actually not then perform an ajax call to the server and update the session. If the session and the facebook js sdk are in agreement over whether the user is logged in or not, do nothing. And if the user's session is unaware that user is logged into facebook but the js sdk says they are, update the server with an ajax call.
I want to create an application that syncs with the users current facebook login status. And I would like that application to login/logout (by executing an ajax call to my server to update their session) whenever they're facebook status changes. This is difficult since I can't seemto reliably detect when a user logs in or out of facebook.
One particular problem I have is when the user loads the page and they're logged into facebook, BOTH the auth.login event and the FB.getLoginStatus() events fire.
My ultimate question is, what combination of facebook-events or general strategy do i have to use to create such an application. A good example of what I'm going for is hulu.com's implementation of facebook login into their website. Thanks for reading this!
<script>
window.fbAsyncInit = function() {
FB.init({appId: '<?=$facebook_app_id?>',
status: true,
cookie: false,
xfbml: true});
FB.getLoginStatus(function(response) {
console.log('getLoginStatus');
console.log(response);
if(response.session){
if(window.module.Globals.prototype.oauth_uid != response.session.uid){
//authenticated user unknown to server, update server and set session
window.module.VCAuth.prototype.session_login();
}
}else{
if(window.module.Globals.prototype.oauth_uid){
//unauthenticated user with authenticated session, update server and unset session
window.module.VCAuth.prototype.session_logout();
}
}
});
FB.Event.subscribe('auth.login', function(response){
console.log('auth.login');
console.log(response);
});
FB.Event.subscribe('auth.logout', function(response){
console.log('auth.logout');
console.log('response');
});
};
(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>
I would recommend using the same callback for all methods. This way you get one authentication code path to worry about. Like this: (which is not that far off from the code you provided)
function authCallback(response) {
if(response && response.session){
if(window.module.Globals.prototype.oauth_uid != response.session.uid){
//authenticated user with invalid session
window.module.VCAuth.prototype.session_login();
}
}else{
if(window.module.Globals.prototype.oauth_uid){
//unauthenticated user with authenticated session
window.module.VCAuth.prototype.session_logout();
}
}
}
FB.getLoginStatus( authCallback );
FB.Event.subscribe('auth.login', authCallback);
FB.Event.subscribe('auth.logout', authCallback);
You said one main problem was:
BOTH the auth.login event and the FB.getLoginStatus() events fire.
Just make sure that session_logout() and session_login() set/unset the oauth_uid before making the async call to the server so that the next time the callback is called the correct state of the VCAuth is set.
Note: auth.logout is not fired every page load because auth.logout implies the user was logged in. It doesn't make sense to fire auth.logout if the user was never logged in right?
Hope this helps.

Categories