Facebook connect is very slow, can I use AJAX? - php

I'm implementing the facebook php sdk and using it for user login/connect.
Everything works as expected, however, at the top of each page, I need to call
$facebook->api('/me') to determine if the user is logged in or not..
This call is very slow, sometimes, taking up to 2 seconds to return.
So, any interaction by the user, always has a 1-2 sec delay before any page loads..
I suspect, it's because, the $facebook->api('/me') call is using httpS ..
Any suggestions....
$facebook = new Facebook(array( 'appId' => 'xxxxxxxxxxxxxxx', 'secret' => 'xxxxxxxxxxxxxxxxx',));
$user = $facebook->getUser();
if ($user)
{
try { $user_profile = $facebook->api('/me','GET'); }
catch (FacebookApiException $e) { error_log($e); $user = null; }
}
$login_parms = array('scope' => 'user_birthday', 'redirect_uri' => 'http://xxx.com/login');
$login_link = $facebook->getLoginUrl($login_parms);
if($user)
{
/* logged in */
}
else
{
/* not */
}

You really shouldn't perform the Facebook API request on each page load. Only do it once when the user logs in. Then you can store the "logged in" flag in the session (or a signed cookie).
If you need to store e.g. some of the user's facebook profile information, also put it in the session or your database.

Add some spinning wheel where login form is, then call ajax on document ready to your php script, script returns false or loged in user data (or more data if you need - redirect url) and then depending on result show form to login or display currently loged in user.
What i mean Javascript will handle all logic depending on what is returned from server, redirects, change UI etc.
Another way is to cache (session with expiration) first call to facebook if user is loged in remember it. And check if that Session variable is present and not yet expired. Only call again when doing some sensitive tasks or get expired.

If you do not need to get "fresh" values from $facebook->api("/me").
Then I would suggest you cache the response, if you use any PHP-framework (eg. Zend, Yii, Codeigniter) this should be really straight forward.
If you're not using a PHP-framework i suggest you still look into the excellent ZF documentation for their cache solution.
Zend Framework - Cache
If you, however, need fresh values each load you can make a simple page that only returns the $facebook->api("/me") part and returns it as bare HTML. Then simply keep a or similar that recieves the response when it's finished.
An easy solution would be using jQuery and just write:
$("#div-id").load("/page-that-returns-facebook-api-me-result");

Related

Check if Facebook user is logged in to app with PHP SDK

I have an app using the Facebook Login API. I take the details of the user and store it in my own database and create my own user id for the user (I also store the facebook id).
Next time the user visits my site, I want to automatically set the session, without having them reconnecting again. So I want to get the Facebook ID of the user (If he is already authenticated) and then check in my database if that ID exists, if so then I set the session.
This is described in the Javascript SDK, however the problem with the Javascript SDK is that the user will not be logged in when visiting the first page, only after a page refresh (Since the Javascript is run after the PHP is executed, so the session is not set when the page loads).
So I want to do this server side, using the PHP SDK.
I tried the following code:
public function isUserLoggedIn(){
$facebook = new Facebook();
$user = $facebook->facebook->getUser();
if($user){
//Use API call for /me which require authentication
try{
$me = $facebook->facebook->api('/me');
//If id_facebook exist, then set logged in session to user id
if($me){
$stmt = $GLOBALS['link']->prepare('SELECT * FROM users WHERE id_facebook=:id_facebook');
$stmt->execute(array('id_facebook' => $me['id']));
if($row = $stmt->fetch()){
$_SESSION['uid'] = $row['id'];
}
}
} catch (FacebookApiException $e) {
$user = null;
//User is not logged in
}
}
}
This code only passes when the Javascript SDK has already authenticated the user and he is logged in. It does not work as intended.
So:
How do I use the PHP SDK to check if the user is authenticated with my App?
I could just set a $_COOKIE myself, is that the way to do it? I suppose that there is an "official" way using the SDK/API, since there is with the Javascript SDK.
I feel I'm a bit late, but here's my two cents:
I log into SO using facebook. Sometimes, in fact, after a day or so passed, i land on this site and after a second or two a little popup tells me that I've been logged in and to refresh the page. It's not really an issue, I just reload the page and I'm happy. That's what you're referring to.
But remember, should you only check the session to retrieve user's ID and facebook data, could lead to problems when the users logged out from facebook (or from your app): your session is not up-to-date with facebook.
That's why using Javascript SDK to login should be better.
I've done a lot of tests and trials today, to understand how the whole thing works (mainly because I encountered a lot of wrong or not complete information given by many "tutorials" out there). The version that did work is the one absolutely copy/pasted from Facebook guide to PHP SDK. Supposing there's an already configured Javascript SDK, I opened my index.php page and started with SDK inclusion:
//autoload is needed to include all sdk classes (not needed using Composer)
require_once ('./inc-fb-sdk/autoload.php');
Then, I had to explicitly tell the SDK to load some of the included classes; this is needed to make use of those classes:
use Facebook\FacebookJavaScriptLoginHelper;
use Facebook\FacebookRedirectLoginHelper;
use Facebook\FacebookRequest;
use Facebook\FacebookResponse;
use Facebook\FacebookSDKException;
use Facebook\FacebookSession;
use Facebook\FacebookRequestException;
use Facebook\GraphObject;
use Facebook\GraphUser;
And, of course, we initialize PHP SDK creating the object (use your AppID and AppSecret in the following line):
FacebookSession::setDefaultApplication('App_id', 'App_secret');
Finally, this is the code from the Guide, with some added comments and echoes, to show if user is logged in or not:
//create object that is used to check login
$helper = new FacebookRedirectLoginHelper();
try {
$session = $helper->getSessionFromRedirect();
} catch(FacebookRequestException $ex) {
// When Facebook returns an error
} catch(\Exception $ex) {
// When validation fails or other local issues
}
//show if the user is logged in or not
if ($session) {
// Logged in
echo ('User is logged in');
} else {
echo ('User is not logged in');
}
Since you're already using the Login API, you only have to test loggin in/out from facebook and then refresh the page, to see the various situations that could happen.
And this should answer the two questions at the end of your post.
Hope this helps.
Note from #parse
You need to pass redirectUrl when you try to call FacebookRedirectLoginHelper(redirectUrl), otherwise you will get 'Missing argument' warning followed by this notice 'Undefined variable: redirectUrl in FacebookRedirectLoginHelper.php on line 77'

I pass Facebook different URLs on a website and they return the same data each time?

I have a problem with requesting data from Facebook. I have tried a few different ways to get the number of likes for an individual page on a website that I manage, but each time I send a specific URL I get the same information back. The share and like and comment totals are the same for each URL that I pass to Facebook.
So for instance I send:
http://api.facebook.com/restserver.php?method=links.getStats&urls=http://thiswebsite.com/page21/
or
http://api.facebook.com/restserver.php?method=links.getStats&urls=http://thiswebsite.com/page49/
and I get the same information returned.
I have Open Graph tags on the site and I think they are implemented correctly but even when I pass URLs directly as show above I get the same results. Could the og tags I have on the site be effecting the results Facebook returns, even if I am manually passing them to Facebook?
Well you have two options to take. One's overly complicated but once you have it working you'll never have to worry about it. The other takes some time but requires a lot less effort.
I'll start with the simple one. Go to https://developers.facebook.com/tools/explorer. Once you get there your uid should already be there just delete every thing after it including the ? and paste in
/accounts?fields=id,name,likes
You will have to make and access token to see the data. You need the manage_pages permission checked on the extend permissions tab.
Once you do that hit submit and you should see in the results all the pages you're admin on the UID of the page, name and number of likes.
The other way is to build an app that handles this for you. Which you will have to register with Facebook and get an app id from them. With that app you can build a program that gets the information for you using php and or java script
Here's a sample of some php you can use.
require "facebook.php";
$config = array(
'appId' => 'app_id',
'secret' => 'app_secret',
'fileUpload' => false, // optional
'allowSignedRequest' => false, // optional, but should be set to false for non-canvas apps
);
$facebook = new Facebook($config);
$user_id = $facebook->getUser();
if($user_id) {
// We have a user ID, so probably a logged in user.
// If not, we'll get an exception, which we handle below.
try {
$path = '/' .$pageId .'?fields=likes';
$pageData = $facebook->api($path,'GET');
$likes = $pageData['likes'];
} catch(FacebookApiException $e) {
// If the user is logged out, you can have a
// user ID even though the access token is invalid.
// In this case, we'll get an exception, so we'll
// just ask the user to login again here.
error_log($e->getType());
error_log($e->getMessage());
}
} else {
// No user, print a link for the user to login
$login_url = $facebook->getLoginUrl();
}
If you choose the longer route let me know I have this whole thing already built.

Facebook php api giving access to users with invalid tokens

I am using the facebook php api to control the access to some parts of my webapp. Basically I am just checking if the user is logged into facebook and the user authorize the app (basic permission) every time the page is load and then printing things according to the state.
Something like, if($check_user_lo_npe) { echo 'Welcome!'; }, simple as that. Well, everything is working fine, until I realize that if the user deletes the app from their users settings in facebook, which means the token gets invalidated, I am still getting a true response from the function check_user_lo_npe even if I know the token is invalid because as I said, the user deleted the app. This is how I am checking the permissions:
function check_user_lo_npe() {
global $facebook;
global $data;
$fb_user_id = $facebook->getUser();
if ($fb_user_id) {
try {
if(!isset($_SESSION['fb_user_profile'])) {
$_SESSION['fb_user_profile'] = $facebook->api('/me');
$temparray = $facebook->api('/me/friends');
$_SESSION['fb_user_friends'] = count($temparray[data]);
}
$data->reg_user($_SESSION['fb_user_profile'],$_SESSION['fb_user_friends']);
return array(true,'');
} catch (FacebookApiException $e) {
$fb_user_id = NULL;
return array(false,$e->getMessage());
}
} else {
return array(false,'');
}
}
I need to realize when the user deletes the app so I can send them to the login screen again, the function is supposed to detect when there is an exception, but somehow I am not getting any... why?
Those $_SESSION variables are set by your app, not by the Facebook SDK right?
Without attempting to access the Facebook session you can't be sure if that session is still active/
If you need to check on each page whether there's still an active Facebook session or not, look at FB.GetLoginStatus() in the Javascript SDK, or make an API call to (for example) /me/permissions to check your access token is still valid
That said, it may be as easy to just have an exception handler which detects when an attempt to access Facebook's API fails, and have it send the user through the authentication flow at that point.
Your if ($fb_user_id) line is probably evaluating to false, which causes you to return array(false,''); in your else statement, never triggering an exception.
If you did get past the ID check, it looks like you are putting data into $_SESSION before they delete the app, and then not re-checking it. Once you have it in the $_SESSION, if you don't go back to Facebook to verify, there is no reason an exception would be thrown.

How to check if a user is logged in to facebook

I am totally new to facebook api and I wanted to ask , whats the easiest and fastest way to know if a person is logged in to facebook.
One solution that I tought of is to send a javascript or php request and see if i get some status code that tells me whether the person is logged in or not (say if it returns 404, then that means he isnt logged in).
update:
I found this easy "hack":
function logged() {
alert('logged');
}
function notlogged() {
alert('not logged');
}
</script>
<script src="http://www.facebook.com/ajax/composer/attachment/question/question.php" onload="logged()" onerror="notlogged()">
But it doesnt work... however, thats the type of code that i am looking for..code that would send a request and if fails, it will throw an error
**update**
I dont want to trigger any suspicion from the user that I am checking if he is logged in. So if there is a use of app_id, then I would think that I need the users permission to use my app..that is a burden cause I will have to take another authentication step.
I cant have the user know that he is being authenticated in any way regarding facebook
If I am reading your code correctly, only if no session is returned do you do the redirect? According to comments in Facebook's example: http://github.com/facebook/php-sdk/blob/master/examples/example.php (great place to this info huh?), even if you get a session back, you can't assume it's still valid. Only trying an API call that requires a logged in user will you know for sure. This is the best way I've seen to reliably determine login/logout status.
if ($session) {
try {
$me = $facebook->api('/me');
if ($me) {
//User is logged in
}
} catch (FacebookApiException $e) {
//User is not logged in
}
}
try This, Hope this will help
include 'facebook.php';
$facebook = new Facebook(array(
'appId' => $app_id, // your application id
'secret' => $app_secret, // your application secret
'cookie' => false,
));
$user = $facebook->getUser();
$loginUrl = $facebook->getLoginUrl(
array(
'scope' => '// put your permission'
)
);
if ($user) {
try {
// Proceed knowing you have a logged in user who's authenticated.
$permissions = $facebook->api('/me/permissions');
} catch (FacebookApiException $e) {
$user = null;
}
}
if (!$user) {
echo "<script type='text/javascript'>top.location.href = '$loginUrl';</script>";
}
If you have a facebook "tab" then limited user information is provided to you as part of the signed_request. And for a facebook tab, you need to create an app.
Otherwise, without an App ID and alerting the user YOU CANNOT DO IT.
There have been hacks in the past, some of the cleverer ones have been to put up comment boxes and measure the hieght of the containing DIV (they used to be larger if logged in) or to include the facebooks FBML tabs to show a log in button (log in was wider) but theses were all stamped out as they were discovered. The same probably goes for the link you tried in your question.
Facebook, for all the debate on rpivacy, won't knowlingly leak information - until you get an app id, ask the user then you can get nearly everything...
Check this topic: https://stackoverflow.com/a/10698594/1789650
This should answer your question. You have to load the javascript SDK to get it to work correctly.

What is the most efficient way to check if user is logged in?

I am pretty familiar with the Facebook SDK and API but I still find myself having a lot of trouble with it. Most of all, speed!
Each time I execute an 'api' call, it takes an additional second or two to return a response. I would therefore like to know what the most efficient and fastest way to detect whether a user is logged in via Facebook is. I am currently using:
// Get the User ID of the facebook user
$facebook_user_id = $this->facebook->getUser();
// If a facebook user exists, then try to get their information
if($facebook_user_id){
try{
// Get the facebook users details
$facebook_user_name = $this->facebook->api('/me','GET');
$this->facebook_logged_in = $facebook_user_id;
return $this->unique_id = $this->facebook_logged_in;
}catch(FacebookApiException $e){
error_log($e);
return false;
}
}else{
return false;
}
This works to a certain extent but it is awfully slow. I literally want to know whether the user is logged in and their session is valid. Is there another way to go about doing this? Why is it so slow?
In most all of facebook's PHP examples, they tend to use $uid = $facebook->getUser(); see
http://developers.facebook.com/docs/reference/php/facebook-getUser/
And then they check if the $uid is 0, then not logged in. if other than 0, then you have their facebook user id.
Looks like you're calling the /me command additionally when you really don't need to. Also to make the /me call quicker, specify the fields=Comma,List,Of,Fields,You,Need so the query can operate quicker. But as noted above, for just getting login status, check for 0 in $uid.

Categories