FB.login() popup blocked only in mobile web application - facebook

For our mobile web application using the Facebook Javascript SDK, we want to check the user's login status, and then display the Facebook login dialog if necessary. The following code is run within a click handler for a given button in our web app:
$('#button').click(function() {
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
// do something with the logged in and authorized user
} else if (response.status === 'not authorized') {
// logged in but has not authorized our app
} else {
// not logged in
FB.login();
}
});
});
Ensuring that the user is not logged into Facebook, this works fine and displays the login dialog for desktop web browsers when the button is pressed, but not for the mobile web (at least not for Android on a variety of browsers, I don't have access to an iPhone currently). Nothing appears on the mobile web app, and when I disable the popup blocker, then I get a prompt asking if I want to allow this popup, which works.
Does anyone know why the behavior is different and/or what the known/standard workarounds are? Thanks!

Your code will not work in all desktop browsers. Some browsers (mobile and desktop) block popups unless they are initiated by a user click. For example,
$('#mybutton').click(function() {
FB.login();
});
will work because the FB.login() function is only being called in response to the user's click. So to fix your code, replace the FB.login() call with some code that displays a 'login' button and text encouraging the user to click that button.

Related

How to bind Facebook onlogin event to customized button?

I know how to use custom button as Facebook login.
Now I'd like to bind onlogin event to customized button, but I don't know how to do.
Original code
<fb:login-button scope="public_profile,email" onlogin="afterLogin();">
</fb:login-button>
<script>
/* Assume that Facebook SDK loaded asyncronously and initilized */
function afterLogin() {
// Do stuff
}
</script>
My code
<button id="cusomized-button" onclick="fbLogin();" onlogin="afterLogin();">
Customized button
</button>
<script>
/* Assume that Facebook SDK loaded asynchronously and initialized */
// Show facebook login modal
function fbLogin() {
FB.login(function() {}, {
scope: 'email,public_profile'
});
};
function afterLogin() {
// Do stuff
}
</script>
Assuming you use version 2.4 of the Graph API, you are able to subscribe to an event called auth.login which is fired whenever the login status changes.
So, if you want to react to when the user logs in, you can do this and your function named afterLogin would be called once the user logs in to your app:
FB.Event.subscribe('auth.login', afterLogin);
Do note that Facebook recommends everyone to listen to auth.statusChange instead, otherwise your application will not know if the user has logged out or deauthorized the application, which would invalidate the token.
Here's an example using auth.statusChange, the response argument passed to the function contains a response object which is detailed here:
FB.Event.subscribe('auth.statusChange', function(response) {
if(response.status === 'connected') {
// `connected` means that the user is logged in and that your app is authorized to do requests on the behalf of the user
afterLogin();
} else if(response.status === 'not_authorized') {
// The user is logged in on Facebook, but has not authorized your app
} else {
// The user is not logged in on Facebook
}
});
As an alternative, the first argument to FB.login is a function which is called after the user returns from Facebook, so you could do something like this:
FB.login(function(response) {
if (response.authResponse) {
afterLogin();
} else {
// The user cancelled the login or did not authorize your app
}
}, {
scope: 'email,public_profile'
});
Here's an alternative using onlogin() in the way you originally wanted.
There's a subtle reason why you may need this:
You are using Facebook login just as a way to login to your own website
User is already connected (has previously connected to your FB)
User is NOT logged into your website.
You don't want to magically log someone in just because they're 'connected' It's not a good user experience.
So you show them the 'Login' button and once clicked you log the user in locally (provided you've established a linkage before).
In that case you do the following in the button code.
onlogin="window.fbOnLogin()"
Then depending upon your environment, somewhere in your code you would need to create a function on window. I'm using an Angular service and doing the following. This is typescript, so omit the <any> part if you're using pure JS.
constructor()
{
// Pure JS
// window.fbOnLogin = this.onLogin;
// Typescript (use lambda to keep 'this')
(<any>window).fbOnLogin = () => this.onLogin();
}
onLogin() {
call_my_server_to_login(token);
alert('Thanks for logging in with Facebook');
}
Now you can display the button to the user (and you secretly already know they're a user because the auto.authResponseChange event (or FB.getLoginStatus()) has told you they are "connected".
Note: None of the events, including auth.login will actually get triggered if you just click the button.
Once they click it FB returns immediately (becuase you're already logged in and connected) and calls your function. You then login the user your own website (you have to do a server side lookup to make sure they already logged in before). If you don't know who the user is then you have to do one of those 'associate your username' pages.

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?

Chrome blocks FB.login()

I have a FB app which need to be integrated in a FB page tab. In app I want to provide a "Signup with FB login" option. This button when clicked should prompt the user to login into FB login dialog. On successful login it should prompt the user to authenticate and allow the app to use his details. Once the user allows the app to access the user details it should then post the details to my website in a new window.
This process works fine when I test the app independently. However when I add the app to the fb page, chrome blocks the Fb login dialog. Before opening the Fb login dialog I check if the user is already logged in FB and has accepted the app. For that I use FB.getLoginStatus(checkLoginStatus); I figured due to this check the context moves to script execution and hence Chrome blocks the login dialog.
Is there a work around for this issue? Help would be highly appreciated.
My code is as follows:
The facebook button is created using span and the id fbc-login-button is given to an a tag.
$("#fbc-login-button").click(function(){
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
console.log('Logged in.');
if (response.authResponse) {
fbAppSignup(response);
}
}
else {
FB.login(function(response) {
if (response.authResponse) {
fbAppSignup(response);
}
},{scope: "email, user_friends",display:"popup"});
}
});
function fbAppSignup(response,myPopup){
var uid = response.authResponse.userID;
var accessToken = response.authResponse.accessToken;
FB.api("/me", function(response) {
$("#social_media_data").val(JSON.stringify(response));
$("#medium").val("facebook");
$("#accessToken").val(accessToken);
$("#socialClickSource").val("fbapp_facebook_signup");
$("#fbSignUp").submit();
return true;
});
}
The example in the Facebook docs is a bit misleading, you should never use FB.login in an asynchronous callback function - and that is exactly what you are doing right now, because FB.getLoginStatus is asynchronous. Always call FB.login on user interaction (mouse click) or it will get blocked by intelligent browsers.
FB.getLoginStatus: on page load, for refreshing the user session and
checking if the user is authorized already
FB.login: on user interaction
Other threads i´ve answered about that problem:
Facebook login popup blocked
FB.api response callback async popup blocked
Sign In with FB issue: FB popup window with the Login dialog is blocked by a web browser

How would I set a PHP session via JavaScript (Facebook SDK)

I'm creating a Login Function using Facebook's SDK. I'm re-using code from a previous project that had a Login button which redirected to a Login Box on the Facebook Domain (i.e. the Login box was not a popup, but redirected the user).
In the previous project when the user would come back to the site after accepting the app, there was a PHP script which created a $_Session:
$user = $facebook->getUser();
if (isset($user)){
$_SESSION['LoggedIn'] = $user;
}
I could then use the 'LoggedIn' session to check if the user was logged in or not, and modify the page based on that (e.g. replace content on the page).
Here's my question - I am now using the JS code that Facebook provides for a popup Login box. I'm guessing after the user Accepted the app from the Login Popup I need to start the session from within JavaScript? The problem is I can't figure out how....
$(".facebookButton").click(function(){
FB.login(function(response) {
if (response.authResponse) {
//User accepted the app -I need to start the SESSION here?
} else {
//User hasn't accepted the app.
}
});
});
Basically what I'm trying to achieve is for the site to know whether the user is logged in or not, even after they've refreshed the page. Thanks for the help!
When the user logs in using the JavaScript SDK, a cookie is immediately dropped on your site with their auth details. The dropped cookie can also be ready by the PHP SDK so all you need to really do is refresh the page for the PHP SDK to detect the user:
$(".facebookButton").click(function(){
FB.login(function(response) {
if (response.authResponse) {
// reload page
location.reload();
} else {
// User hasn't accepted the app.
}
});
});

Login popup vs lightbox in Facebook canvas app

I have a Facebook canvas app, which calls FB.getAuthResponse() first and, if necessary, FB.login(). The documentation of the JS SDK clearly states FB.login() opens a login popup window, which is correct when I hit the canvas URL directly. However, when I do the same thing in the canvas page as an anonymous user a "Not logged in" lightbox appears and redirects to the login page.
Is there any way of unifying this behaviour (preferably always using popup)?
Turns out it's possible to explicitly specify the 'format' of the login window when using JS SDK - FB.login() accepts the display parameter which defines the display mode of a window.
The final code looks like this:
var authResponse = FB.getAuthResponse();
if (authResponse && authResponse.signedRequest) {
addFieldsAndSubmit(authResponse.signedRequest);
} else {
FB.login(function(response) {
if (response && response.authResponse) {
addFieldsAndSubmit(response.authResponse.signedRequest);
}
}, {scope:'email', display: 'popup'});
}