In about 0.3% of users, I can't get their FB ID with JS API. On some occasions I have gotten it before for those users. What could be the cause of this and any ideas on how to fix it?
As far as I know most of those users were on Windows and using firefox.
My code:
window.fbAsyncInit = function () {
FB.init({
appId : "xxxx",
status : true,
cookie : true,
xfbml : true,
oauth : true
});
FB.Canvas.setSize({width:$("#mainbody").outerWidth(),height:$("#mainbody").outerHeight()});
FB.getLoginStatus(function (response) {
if(response.authResponse){
if(response.authResponse.userID){
fbId = response.authResponse.userID;
$("#hiddenFbId").val(fbId);
setSession();
}
}
if (response.status === 'connected') {
FB.api(
"/me?locale=et_EE",
function (response) {
if (response && !response.error) {
fbName = response['name'];
fbId = response['id'];
$("#hiddenFbId").val(fbId);
fbEmail = response['email'];
setSession();
}
});
} else {
FB.login(function (response) {
if (response.authResponse) {
if(response.authResponse.userID){
fbId = response.authResponse.userID;
$("#hiddenFbId").val(fbId);
setSession();
}
FB.api(
"/me?locale=et_EE",
function (response) {
if (response && !response.error) {
fbName = response['name'];
fbId = response['id'];
$("#hiddenFbId").val(fbId);
fbEmail = response['email'];
setSession();
}
});
} else {
fbDenied = true;
}
}, {
scope : 'public_profile,email,user_likes'
});
}
});
}
Never call FB.login in the asynchronous (!) callback function of FB.getLoginStatus. Some browsers block the login popup if you do that, you always need to call FB.login on user interaction - and calling it on page load is a bad idea anyway. Don´t force the user to authorize your App right when they enter your App and before they know what your App is about.
FB.getLoginStatus on page load to refresh the User Token and to check if the user is authorized
FB.login on mouse click
It is also easier that way to remove some redundant code and move your FB.api call to a function.
It may or may not solve your problem, but it´s definitely important and a commong source of errors.
Related
In my website, users can post to their FB wall from my website. I,am using graph api for that. My api code is,
FB.api(
"/me/photos",
"POST",
{
"caption": "My caption",
"url": "My image url"
},
function (response) { console.log(response);
if (response && !response.error) {
$('#post_response').html('See feed');
}
}
);
During this api call getting an error,
code: 200
message: "(#200) Requires extended permission: publish_actions"
type: "OAuthException"
My Fb login Api is,
FB.login(function(response) {
if (response.authResponse) {
//user just authorized your app
document.getElementById('loginBtn').style.display = 'none';
getUserData();
}
},
{
scope: 'email,public_profile,publish_actions,manage_pages',
auth_type: 'rerequest',
return_scopes: true
}
);
I also tried,
1)
FB.login(function(response) {
if (response.authResponse) {
//user just authorized your app
document.getElementById('loginBtn').style.display = 'none';
getUserData();
}
},
{
scope: 'publish_actions'
}
);
2)
FB.login(function(response) {
if (response.authResponse) {
//user just authorized your app
document.getElementById('loginBtn').style.display = 'none';
getUserData();
}
},
{
scope: 'publish_actions',
auth_type: 'rerequest'
}
);
By calling api,
FB.api("/me/permissions", function (response) {
console.log(response);
});
I understood that, only getting 'email,public_profile' permissions.
How to get 'publish_actions' permission??
Is there any other methods to do this?? I want to post image post to users wall and users page...
Please help me to fix this issue...
Thanks in advance.
Make sure that you have added the FB account to test user under FB app settings >test user . Because In order to use permissions like publish _action your app needs to be approved by Facebook,but with test users you can test the functionalities.
Here's code flow, first is the login and it's work good, but after that i want to immediately call feed function, that's probably the reason why browser blocked it, is there any other way how i can do this? Its work good if the display is set to iframe, but i really want it as a popup. Tahnks.
Share
function
function fblogin() {
FB.login(function(response) {
if (response.authResponse) {
FB.api('/me', {fields: 'last_name, first_name, gender, email, id'}, function(reslog) {
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
postToFeed(reslog.gender);
}
});
});
} else {
//console.log('X');
}
}, {scope:'email'});
}
postToFeed
function postToFeed(gender) {
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
FB.ui( {
method: 'feed',
display: 'popup',
[...]
}, function( response ) {
console.log( 'before',response );
if ( response !== null && typeof response.post_id !== 'undefined' ) {
console.log( 'done',response );
}
});
}
});
}
You have to call FB.ui dialogs directly on user interaction (= in the callback function of a mouse event). FB.getLoginStatus is asynchronous, that´s why (good) browsers block it.
Use FB.getLoginStatus on page load instead, and store the status. Or better: remove it, because you don´t need to authorized a user for the FB.ui dialogs. And in your code it would not make any sense, because you only use it after FB.login and even after an API call - so the user is surely logged in.
FB.login is asynchronous too, and trying to present a share dialog to the user immediately after login is not only annoying for the user, it´s also against the rules imho. I would count that as "incentivizing":
Only incentivize a person to log into your app, enter a promotion on
your app’s Page, or check-in at a place. Don’t incentivize other
actions.
Source: https://developers.facebook.com/policy/
New code:
HTML:
Share
JavaScript function "postToFeed":
FB.ui( {
method: 'feed',
display: 'popup',
[...]
}, function( response ) {
console.log( 'before',response );
if ( response !== null && typeof response.post_id !== 'undefined' ) {
console.log( 'done',response );
}
});
I have a site that uses the FB SDK to log in the user and make a FB graph call to get their info. The issue is that it doesn't work in IE9, 10, or 11 - but it works in Chrome and Firefox. The code is as follows:
<script src="https://connect.facebook.net/en_US/all.js"></script>
<script>
FB.init({
appId: '{ AppId }',
xfbml: true,
cookie: true
});
</script>
To initialize the SDK. Then we have a client side library that has the following functions to get the user's facebook information.
window.rest = {
getUserFbInfo: function(fn){
rest.checkLoginStatus(function(){
FB.api('/me', function(userData){
console.log('userData', JSON.stringify(userData))
fn(userData);
});
});
},
checkLoginStatus: function(fn){
FB.getLoginStatus(function(res){
if (res.status === 'connected'){
fn();
} else {
FB.login(function(){
FB.getLoginStatus(function(res){
if (res.status === 'connected'){ fn(); }
else { return; }
});
}, { scope:'email,user_birthday,user_location,publish_actions,user_likes' });
}
});
}
};
The problem is in the first function. The output I get from the console log (stringified to make it easier to debug in IE) is this:
userData {"error":{"type": "http", "message": "unknown error"}}
Not shown, but a console log of the response from FB.getLoginStatus returns that the user is connected. Thanks for the help!
If anyone cares about this issue, IE needs P3P headers to be set on the server.
I have a problem with my angular app- after a user signs in, if he hits the refresh button, the signin info is lost and the app redirects to the log in page. I found a SO answer for something similar here using $cookieStore but I don't think it can work for me as I'm not using cookies. Can anyone suggest a solution? Here's my authorization service-
var app = angular.module('myApp.services');
app.factory('SignIn', ['$resource', '$q', function($resource, $q) {
var signInUrl = 'https://example.com'
var API = $resource(signInUrl, {}, {
signIn: {
withCredentials: true,
url: signInUrl + '/session',
method: 'POST'
},
signOut: {
url: authApiUrl + '/session',
method: 'DELETE'
},
currentUser: {
url: signInUrl + '/users/#me',
method: 'GET'
}
});
var _currentUser = undefined;
return {
isAuthenticated: function() {
return !!_currentUser;
},
getUser: function(){
var d = $q.defer();
// If _currentUser is undefined then we should get current user
if (_currentUser === undefined) {
API.currentUser(function(userData) {
_currentUser = userData;
d.resolve(userData);
}, function(response) {
if (response.statusCode === 401) {
_currentUser = null;
d.resolve(_currentUser);
} else {
d.reject(response);
}
});
} else {
d.resolve(_currentUser);
}
return d.promise;
},
signIn: function(username, password){
var d = $q.defer();
API.signIn({email: username, password: password}, function(data, headers){
_currentUser = data;
d.resolve(_currentUser);
}, d.reject);
return d.promise;
},
signOut: function(){
var d = $q.defer();
API.signOut(function(){
_currentUser = null;
d.resolve();
}, d.reject);
return d.promise;
}
};
}]);
If you just need to keep track of the _currentUser data past a refresh then you could use sessionStorage within the browser. That extends all the way back to IE 8 and we really shouldn't be supporting any browsers before that anyway.
Usually these things are done with cookies though. When the client first makes a connection to the server (even before the first API call in some cases) a cookie is sent to the client so the server can maintain a session associated with that particular client. That's because the cookie is automatically sent back to the server with each request and the server can check its local session and say, "Oh, I'm talking to this user. Now I can use that additional piece of context to know if I can satisfy their API call or not."
You don't show any of your other API calls here but I'm guessing that you're sending something out of the _currentUser with each API call to identify the user instead? If so, that certainly works, and it avoids the need to synchronize cookies across multiple servers if you're clustering servers, but you're going to have to use something local like sessionStorage or localStorage that won't get dumped like your current in-memory copy of the data does when you refresh the page.
I am trying to implement Facebook login on my website as part of authentication and using Facebook JavaScript SDK for that.
used a simple code as
window.fbAsyncInit = function() {
FB.init({ appId: 'xxxxxxxxxxxxx', //change the appId to your appId
status: true,
cookie: true,
xfbml: true,
oauth: true});
function updateButton(response)
{
if (response.status === 'connected')
{
$('#fb-auth').on('click',function(){
FB.api('/me', function(info) {
login(response, info);
});
//FB.logout(function(response) {
//logout(response);
//});
});
}
else
{
$('#fb-auth').on('click',function(){
FB.login(function(response) {
if (response.authResponse) {
FB.api('/me', function(info) {
login(response, info);
});
}
else {
;
}
}, {scope:'email,user_birthday,status_update,publish_stream,user_about_me'});
});
}
}
FB.getLoginStatus(updateButton);
//FB.Event.subscribe('auth.statusChange', updateButton);
};
Facebook login works fine but what I am trying to do is when next time they try Login with Facebook , they should get login pop-up and option to login as another user.
After first login , next time when they are trying to login with facebook again and they are logged into facebook in another tab its just redirecting them to logged in page without any pop-up or anything.
Can anyone please give me some pointer as what need to be done to achieve that.
If you want to login the user everytime he visits the app, you should implement FB.logout, when you get the status as connected on getLoginStatus() when the app starts.
So the session when be destroyed and then you can call FB.login again. Just like-
// app starts here
FB.getLoginStatus()
{
if(status == "connected")
// call FB.logout()
// call FB.login()
else
// call FB.login()
}