FB.getLoginStatus with "force"=true only working for some usersadmins when used twice - facebook

We have a requirement on our site which forces a user to like a fan page before they can proceed on our site. Since Facebook requires a user to allow access via an app for this type of data, we have an initial call to FB.getLoginStatus which sends the user down three paths, based on the 3 responses (unknown, not connected, connected). Our problem exists in the "unknown" branch. This initial call to FB.getLoginStatus works fine for everyone, if the user is unknown (logged out) we show them the Like Box social widget, then the user clicks on it and logs in (thus liking the page), and then we use the callback of FB.Event.Subscribe('edge.create') to run FB.getLoginStatus again (to check if the user was simply logged out but has previously allowed our app). At that point, if the user previously allowed our app, we allow them to continue, if not we show them an "allow" button and on that user interaction and callback we allow the user to continue. This logic flow works for a hand full of people, including a few of the administrators listed for the app, but not the majority of users. On the second call to FB.getLoginStatus we are using the second parameter "force=true". Can anyone give insight into this behavior and/or point to a thread with a similar glitch? Thanks in advance, this one is a head scratcher!

FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
} else if (response.status === 'not_authorized') {
} else {
}
}, {force: 'true'});

Related

FB.login distinguish successful login from cancel if the user connected the app before

We have an FB.login call like this:
FB.login(function (response) {
if (response.status === 'connected') {
responseFunction(response.authResponse.userID);
} else {
responseFunction(null);
}
}, { scope: requiredPermissions.concat(optionalPermissions).join(','), return_scopes: true });
It properly detects a canceled login if the user didn't connect to the app yet. However, if the user is already connected when they cancel the login, response looks like this:
authResponse: {
accessToken: "token",
data_access_expiration_time: 1560437437,
expiresIn: 86963,
reauthorize_required_in: 7776000,
signedRequest: "bababa",
userID: "userid"
},
status: "connected"
Almost exactly like a successful login response. Luckily, there is also a grantedScopes field in the response if the login has been finished properly (because of a return_scopes option). However, using it to distinguish between the 2 seems unreliable and hacky.
Is there a better way?
Thank you in advance!
Update:
Why not use FB.getLoginStatus instead?
For the context: in my case, FB.login is used to be granted access to the user's pages. It is not used to log them into the app, per se.
I'll be happy if someone points at a mistake in my reasoning. Here it is:
Calling FB.login right after FB.getLoginStatus is unreliable due to the modal block in browsers. FB.login needs to be called synchronously within a click handler.
FB.getLoginStatus result may and will expire if called before showing the button calling FB.login. A user may and will spend a lot of time on this particular page before clicking the button.
That's why the button click handler immediately calls FB.login. It helps avoid both of the mentioned issues.
I ended up using the presence of grantedScopes in response as an indicator of a complete login.

Why do I get this warning message on my facebook login page?

I'm trying the Facebook login API for the first time on a web app deployed locally.
I init the API with the snippet in their documentation and have a button on my HTML page
<button type="button" onclick="fbLogin()">
Where fbLogin() is
function fbLogin() {
FB.login(function(response) {
console.log(response);
// handle the response
if (response.status === 'connected') {
// Logged into your app and Facebook.
} else if (response.status === 'not_authorized') {
// The person is logged into Facebook, but not your app.
} else {
// The person is not logged into Facebook, so we're not sure if
// they are logged into this app or not.
}
}, {scope: 'public_profile,email,user_friends'}); // TODO: If the user doens't provide the email address prompt it for email. Also, don't ask for friend list when its a simple logout maybe? Specify why it's needed first. If it doesn't provide the friends access, re-prompt the request, explaining him it can have a more social experience if he accepts (can see when its friends win and congratulate with them, (we can also prom him to invite some friends))
}
When I try to log in the message
"You are using a display type of 'popup' in a large browser window or tab. For a better user experience, show this dialog with our JavaScript SDK without specifying an explicit display type. The SDK will choose the best display type for each environment. Alternatively, set height and width on your window.open() call to properly size this dialog if you have special requirements precluding you from using the SDK. This message is only visible to developers of your application."
shows up.
Screenshot
As you can see though, I am not specifying any specific display type; so I really don't know what to do with this message.
Other Google entries didn't have a solution for this problem.
What action do I need to take in order to remove it?

Facebook getLoginStatus() function and phonegap not updating status

I am currently developing an app on Android using phonegap and would like to use Facebook in the app. I have created an app on Facebook called say "Test". When I am not logged into "Test" but I am logged into Facebook (Facebook app on the Android device) and run the getLoginStatus() function I get a response of unknown instead of not_authorized. Thus my first question is this intended? Am I meant to get a response of unknown or is this an error from phonegap and I'm meant to get a response of not_authorized.
The second question is, when I login into the Facebook app called "test" everything runs as it should (Facebook user gets registered for "test"). When I call the getLoginStatus() function it works perfectly fine and says I'm connected with no problems.
BUT
If I go into Facebook and remove the app "test" from my FB account and then run the android app again and run the getLoginStatus() function is STILL says that I have the app "test" registered to my Facebook account but this is no the case!! Note that I do in the code make sure that I call the server every time instead of using a cached result by the JS SDK. Now my Second question is. Is this meant to happen? Or if not is it a Facebook or Phonegap problem (Phonegap either keeps getting the cached response or Facebook doesn't update their side quick enough?)
Here is code:
function getLoginStatus()
{
FB.getLoginStatus(function(response)
{
alert(JSON.stringify(response));
alert(response.status);
if (response.status == 'connected')
{
alert('logged in');
FB.api('/me',function (response) {
if (response.error)
{
alert('There is an error');
}
else
{
alert(response.name);
}
});
}
else
{
alert('not logged in');
}
},true);
}
Any response would really really be appreciated!!
When I am not logged into "Test" but I am logged into Facebook (Facebook app on the Android device) and run the getLoginStatus() function I get a response of unknown instead of not_authorized.
not_authorized: You get not_authorized when the user is logged into facebook but has not authorized your app. If you transfer the guy to facebook homepage, he enters username and password and cancels authorization, thereafter you get not authorized. IF the guy is logged into facebook,and your app hasn't transferred him to fb to authorize yet, you still get not authorized
https://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus/
unknown: If the user is not logged into facebook, you get a status of unknown.
So logged in, not authorized : not_authorized
Not Logged in: unknown
If I go into Facebook and remove the app "test" from my FB account
I am guessing it takes a while for these changes to propogate. If the user has authorized the app in the current context, it will stay authorized for a while(or until he logs off). I don't think there's anything wrong with this personally
This is not a phonegap issue. unknown is one of the valid responses from the getLoginStatus function. See the facebook API documentation for information about this funciton. There, they describe the unknown response as:
the user is not logged into Facebook at this time and so we don't know if they've authenticated your application or not (unknown)
As to your second question, the problem you are seeing is because by default, the getLoginStatus function caches its response for performance reasons. However, they provide you with a way to force a refresh of the status. You can do this by passing a second parameter, Force into getLoginStatus.
FB.getLoginStatus(function(response) {
// this will be called when the roundtrip to Facebook has completed
}, true); // The second parameter, called 'force' by default is False. True signifies that you want to force a call to the server so you can see the latest login status.
You can read more about that Force parameter by looking at the above API documentation link and searching for the 'Force' parameter.
By the way, I had temporarily deleted the answer as I had answered without knowing how to respond to the second question, but undeleted it after finding out the reason behind your issue.

How do I pop up a dialog from Facebook to request the user to "allow" for open graph?

In my Facebook application, I am requesting 3 scopes: email,publish_stream,publish_action
I am using the FB.login function. These 2 steps pop up.
When the user clicks "Cancel" in the first step, FB.login will show "status: unknown" as the response object.
However, when user clicks cancel in the second step, FB.login shows it as "status:connected" and treats it as if the user accepted everything.
I recently learned that you can check if the user allowed the 2nd step using
FB.api('/me/permissions', function (response) {
console.log(response);
} );
My question is...knowing that the user denied the open graph step, how can I pop that dialog up again?
You are correct, the 2nd stage of the Auth Dialog is optional, the user does not have to accept all of the extended permissions you ask for, or any of them, as it states in the Permissions sections of the auth dialog documentation:
The user will be able to remove any of these permissions, or skip this
stage entirely, which results in rejecting every extended permission
you've requested. Your app should be able to handle revocation of any
subset of extended permissions for installed users.
The best approach I think is to have your app manage with what the user accepts, but if you HAVE to have the permission(s) in the optional stage (extended permissions) then this is what you can do:
FB.init({
....
});
var requiredPermissions = ["email", "publish_stream", "publish_action"];
function checkPermissions(response) {
var ok = true;
if (!response.data || response.data.length != 1)
ok = false;
else for (var perm in requiredPermissions) {
if (!(perm in response.data[0])) {
ok = false;
break;
}
}
if (!ok)
login();
else
console.log("Hey there user who granted all the required permissions");
}
function loginCallback(response) {
if (response.authResponse) {
FB.api("/me/permissions", checkPermissions);
}
else {
console.log("User cancelled login or did not fully authorize.");
}
}
functoin login() {
FB.login(loginCallback, { scope: requiredPermissions.join(",") });
}
I haven't tested this code, it's a nudge in the right direction though.
Also, this code will go on forever until the user accepts all permissions or just gives up, you should somehow let him know that you need those permissions and about to send him for the auth dialog again.
Edit
I keep forgetting to include this with my answers:
Calling FB.login opens a new pop-up window, and browsers usually blocks that unless it's a result of a user action, as it says in the docs:
Calling FB.login results in the JS SDK attempting to open a popup
window. As such, this method should only be called after a user click
event, otherwise the popup window will be blocked by most browsers.
It also says there:
If you need to collect more permissions from users who have already
authenticated with your application, call FB.login again with the
permissions you want the user to grant. In the authentication dialog,
the user will only ever be asked for permissions they have not already
granted.
Which means that it's a way to do what you want, the popup probably did not open because it was blocked by your browser.
You need to modify the code I gave you so that every time you call the login function it's after the user interacted with your page, i.e.: display a message saying "the application needs this and that permissions, please click this button to continue" which then will call the login function.

How to specify Extended Permissions in the JS SDK Auth request

UPDATED TO BE MORE CLEAR (hopefully :)):
Related to this page, specifically the SSO section: http://developers.facebook.com/docs/authentication/
You've got the option Facebook says to use either that facebook connect button (whatever connect means nowdays with Facebook is a grey fog to me now) or just roll your own image as a button and on click call FB.Login().
So I tried the facebook button route which lead me to a complete brick wall. I mean I can get it working, auth, login, all that but I have no clue how to pass extended permissions through this entire process with the button:
window.fbAsyncInit = function () {
FB.init({ appId: facebookApplicationID, status: true, cookie: true, xfbml: true });
FB.Event.subscribe('auth.sessionChange', function (response) {
...rest of code
Ok, how do I attach extended permissions to this call? Of course you can do it easily if using Login() but why doesn't facebook show any examples or state whether the perms parameter exists in terms of placing it somewhere in this process of using that button!
related links: http://forum.developers.facebook.com/viewtopic.php?pid=248096#p248096
I don't even know why they have that button in here when it looks to me like most everyone is just simply calling Login() inside the Init. I assume then calling Login() still manages the SSO in terms of cookie, etc.?
Is anyone using this button or are you just going with FB.Login() ?
I'm running this in an iframe on our own hosted website...not embedding code into the facebook site itself (which I believe is called canvas right?).
RTFM. Yes, I mean friendly.
Right below the Single Sign-on section is the Account Registration Data section and I've copy-pasted this from there.
<fb:login-button perms="email,user_birthday"></fb:login-button>
Not exactly sure what you are trying to accomplish here. If you want to get information about your user or take actions on their behalf on Facebook, you need the user to tell Facebook it's okay to do so (this only needs to happen once) which is why you need to you call FB.login as described here: http://developers.facebook.com/docs/reference/javascript/FB.login.
FB.login(function(response) {
if (response.session) {
if (response.perms) {
// user is logged in and granted some permissions.
// perms is a comma separated list of granted permissions
} else {
// user is logged in, but did not grant any permissions
}
} else {
// user is not logged in
}
}, {perms:'read_stream,publish_stream,offline_access'});
They need to enter in their password to prove it's really them to authorize your app. If you need extended permissions, the second parameter in FB.login allows you to do this.
If the user is already logged in to Facebook (for example in another tab) then there's no need to log in and the login screen should be skipped. If the user is both logged in an has already authorized your app then there's no need to call FB.login.
You check check the user's login status (and permissions) with FB.getLoginStatus: http://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus before deciding whether or not to call FB.login.