What I want to do is user must like my page first then only can go to my facebook apps, but I have no idea why I cannot detect it and I had var_dump my page liked, result is NULL
here is my code
$request = $_REQUEST["signed_request"];
list($encoded_sig, $load) = explode('.', $request, 2);
$fbData = json_decode(base64_decode(strtr($load, '-_', '+/')), true);
var_dump($fbData["page"]["liked"]);// output is NULL
if (!empty($fbData["page"]["liked"]))
{
echo "This content is for Fans only!";
} else {
echo "Please click on the Like button to view this tab!";
}
Any idea how to do it?
Have you made sure there is as signed_request parameter?
It only gets transmitted to your app once the page is initially loaded into the Facebook iframe – it won’t be there anymore once you start navigating inside your app.
Best thing to do IMHO is to parse the signed_request if not empty, and safe the results into your own session.
Btw., parsing it yourself is rather time-consuming – I’d suggest using the PHP SDK and use Facebook::getSignedRequest() – that method gives you all the data in decoded form, if there was a signd_request parameter.
So here’s what I usually do:
if($signed_request_data = $Facebook->getSignedRequest()) {
$_SESSION['signed_request_data'] = $signed_request_data;
}
You can call that code on every page – only if the method actually returns data, your session gets updated.
You need the permission user_likes to check if they liked your Facebook App but $fbData["page"]["liked"] is referring to your Facebook App Page which is seperate.
To edit your App Page go to App Settings > Advanced > Near the bottom you will see App Page
To use the permission user_likes to check see this SO Answer On Detecting if a User Likes a Facebook App
Related
I'm new to Facebook APIs and have to do something which seems to me like it should be fairly simple, but there are so many ways to turn I'm looking for someone who knows the terrain to point me in the right direction. (I may already be pointed in it, but I'm not having success so I'm asking for help.)
I have a client website which has the Like button on certain pages (along with much other content of course). That is already implemented using an iframe tag, but I can do it a different way if need be.
What is not implemented and needs to be is that if the visitor has Liked that page, I want to show one block of content, and if he hasn't I want to show a different block. Most of the page would be identical, so I can't redirect or change the URL to accomplish this. Nor can I prompt the user for permission. I have to silently determine whether the visitor Likes the page he's currently on.
Ideally, what I'd like is a php function that will return a boolean whether the visitor likes the current URL or not. Here it is in pseudocode:
function VisitorLikesPageInFacebook($url) {
# $url = the URL to this page (NOT a Facebook page)
# if visitor is not logged into Facebook, return false
# if visitor is logged into Facebook and likes $url, return true
# if visitor is logged into Facebook and does not like $url, return false
# if anything else happens, return false
}
Can this be done using php? Do I need the Facebook PHP SDK? What settings do I need to have in my Facebook app, or better is there any possible way I can do this without creating a Facebook app? I've tried using $facebook->getUser() but it returns 0 unless I first go to the $facebook->getLoginUrl() address and give permission, which I can't expect visitors to the client site to do. I've tried $facebook->getSignedRequest() but it returns NULL. Is there a setting in my Facebook app that I need to set, or some other call I need to make first? Will I or my client need to have https to give the Facebook app a secure location?
The other piece of this puzzle is that I want the page to refresh when the Like button on it is clicked, and presumably when it does the return value of the above function will change. For that I assume I'll need to use the JavaScript SDK and subscribe to the Like event. Is that right? (My fallback approach, if I can't do what I need to via php, is to use the JavaScript SDK, subscribe to the Like event, and set or unset a cookie depending on whether he Liked or Unliked. Then read the cookie with php. JavaScript is nowhere near as familiar to me as php, so I'll avoid it except where required.)
If anyone can point me in the right direction, I'd be very happy! Thanks in advance.
$pageID= 'YOURID'; // Used below to fetch
$config = array(
'appID' => 'UR_ID',
'secret' => 'UR_SECRET',
'allowSignedRequest' => false,
);
$facebook = new Facebook($config);
$user_id = $facebook->getUser();
?>
<html>
<head><title>FB TEST</title></head>
<body>
<?php
if($user_id)
try {
$user_like = $facebook->api('/'.$user_id.'/likes/'.$pageID,'GET');
if(!$user_like){
echo 'User doesnt like';
} catch(FacebookApiException $e) {
$login_url = $facebook->getLoginUrl();
echo 'Please auth us here.';
error_log($e->getType());
error_log($e->getMessage());
}
I'm utilizing the Facebook PHP SDK on its own. I do not want to use the JS SDK at all.
Because getUser(); from the SDK can return a user id even if the user is not logged in, I have opted for using a try/catch statement to check if the user is logged in.
try
{
$me = $CI->facebook->api('/me');
$CI->our_fb['is_fb']='YES';
echo "hello";
}
catch(FacebookApiException $e)
{
echo "catch";
}
This statement is included in the global include file of all of my files (for simplicity).
So, depending on the situation, I generate a Facebook login URL. The expected functionality is that the user logins to Facebook, authorises the app, is returned to the redirect URI set in the login URL at which point the try statement will execute, and $CI->our_fb['is_fb'] will be set.
This is however not happening.
If the user is already logged into Facebook and the app is authorised, it works perfectly. SUCCESS
If the user is not logged into Facebook, once redirected the variable is not set. FAILURE
If the user is logged in but the app is NOT authorised after redirect the variable is not set. FAILURE.
In the latter two cases if you simply refresh the page, the variable is set - SUCCESS. Refreshing the page is however unnecessary/pointless extra effort.
My problem is that if you need to login to FB/or authorise the app e.g the first time you login with FB, you have an additional unneeded refresh, and I don't know why.
I suspect it is something to do with the cookie/session? Which saves the access token that I assume is returned/passed to the SDK automatically not being set at the same time?
Anyone got any ideas?
If you're having an app on facebook (tab or canvas). PHP SDK only get the User ID on initial loading of a page because a signed_request is sent with the request to your app.
But, when the app refreshes, the signed_request is lost (as it's facebook who send it).
So, in this case, you can append the signed_request to every URLs your use in your app - but that's really not optimal as the signed_request won't be regenarated - neither refreshed.
Your only real option is to rely on the JS SDK to set cookie correctly and allow getUser to work as expected. This is required because you're considered as a third-party app in Facebook (being in an iframe) and most browser will block you from setting cookies - so you need a work around handled by the JS SDK for you. You can search for cross-domain cookies or third-party cookie for explanation about the workarounds, but these workaround only work via JS scripting and iframe management.
Also, be sure to setup the JS SDK correctly: channel file, cookie allowed, and send P3P headers (for IE).
You can also check this related question: A proper approach to FB auth
About website, the same mostly stays (but you have no signed_request). At this point, seriously consider using the JS SDK as it's way easier. Or else, you can make sure your app flow follow these guidelines: https://developers.facebook.com/docs/concepts/login/login-architecture/
The way I am seeing this is, you are trying to avoid that refresh if the user is not logged in and precedes to log in after the page has initially loaded.
So what you can do is make an ajax request to another page on your site, say for example id.php, which just loads the php sdk and echo $userid; and then you can grab the user id after login without the refresh.
Basically the cookie is used to save the signed request and session is used to save 'state', 'code', 'access_token', 'user_id'. If the above are present PHP SDK uses them, no matter if they are valid or not.
I think your problem lies in the CODE sent by facebook. Specifically these lines in base_facebook.php:
if ($code && $code != $this->getPersistentData('code')) {
$access_token = $this->getAccessTokenFromCode($code);
...
protected function getAccessTokenFromCode($code, $redirect_uri = null) {
if (empty($code)) {
return false;
}
if ($redirect_uri === null) {
$redirect_uri = $this->getCurrentUrl();
}
...
Because CODE is issued for specific url sometimes there is such situation: Visitor arrives on www.example.com. He givies permissions and is redirected to example.com/login. But the code is not valid there, so the getUserAccessToken returns false. When you refresh the page you get same urls and everything's fine.
You're on the right track of not using getUser() because as I wrote above it's taken from the session if available.
SO here's what I am after. I have a FB page tab that runs the content of the site https://site.com/
I set up a FB share link to share a page aboutus.html. When I share it FB allows me to share this URL https://site.com/aboutus.html, but how can i send the traffic directly to the iFrame on the page tab? For example https://www.facebook.com/fan_page/app_331267943480920398/whatever_aboutus.html
I know it is possible because I saw it one day - cant remember now where.
Thanks.
You can't pass in filenames this way, that's only supported on Canvas Apps.
The best workaround to replicate this is using the app_data parameter. Basically, have your landing page (as defined in your app settings), be some kind of server side script which listens to the Signed Request, specifically the app_data parameter. Then you have that script load content based on the contents of that.
So as an example, let's imagine I want to load http://mybasedomain.com/foo.php or http://mybasedomain.com/bar.php. I direct users to https://www.facebook.com/PAGENAME/app_APPID?app_data=foo or https://www.facebook.com/PAGENAME/app_APPID?app_data=bar, then on my landing page, I have a simple if/else statement to parse that and render the relevant content -
<?php
// Assumes you have this parse_signed_request function - https://gist.github.com/872837
// And a $config array, which contains your app_secret
$signed_request = parse_signed_request($_REQUEST['signed_request'], $config['AppSecret']);
if ($signed_request['app_data'] === 'foo') {
include('foo.html');
} else if ($signed_request['app_data'] === 'bar') {
include('bar.html');
} else {
include('index.html');
}
I have a probleme with my Signed Request on my facebook application. The first time is good, and i know if the user like or not my app. But when I reload the application (link, form, like) i loose the Signed Request, (only refresh [F5], and unlike works)..
I realy don't understand why ??
Links don't work anymore :(
This is my test page : https://www.facebook.com/pages/TestCactOos/255835411190164
And the test app : https://www.facebook.com/pages/TestCactOos/255835411190164?sk=app_335457189856398
On app, you can see $facebook, $_REQUEST and $_SERVER informations.
Thank you all for your time and help.
The signed request is in the header of the referral from Facebook. It's not maintained from link to link, since the subsequent referrals will be from your own pages. Use the signed_request to get some info and keep that in your session between pages.
You are just one time able to get the signed_request. That is exactly when Facebook loads your App in an iframe. Then you must have to save the signed_request for further usage (subpages). There you have to check for the data via $_REQUEST or fall back to your stored signed_request values.
Here is an small example of the fbHelper component. I hope this might give you some ideas how to handle the issue:
Source: http://www.facebook.com/HelperComponentlCommunity/app_412923142052609
if(array_key_exists('signed_request', $_REQUEST))
$signed_request = $_REQUEST['signed_request'];
elseif(array_key_exists('signed_request' . $this->pageId, $_SESSION))
$signed_request = $_SESSION['signed_request' . $this->pageId];
else
return false;
$facebook_data= $this->parse_signed_request($signed_request);
As per the documentation in the following link, we can get the user id if the uer will interact with the form..
http://wiki.developers.facebook.com/ind … d_Policies
"If a viewing user interacts with the tab (like submits a form, takes an action that causes an AJAX load of new content, or follows a relative URL that loads on the tab), that user's UID is sent to the application as the fb_sig_user parameter, the profile owner's user ID is sent as the fb_sig_profile_user parameter. The viewing user's session key is key is sent only if the user authorized the application. "
In my fan page tab am I have an AJAX form which the user can submit with some value.. now I need the users id also.. how can I get this..
I tried to get the value in my AJAX submit page using $_POST['fb_sig_user'] with no success.. can anyone help me with this please..
You won't be able to get the id of the user using $_POST['fb_sig_user'] unless you authenticate the user by having this in the facebook's ajax function:
ajax.requireLogin = true;
For example, I'm retrieving it fine with this:
function do_ajax(url, div_id)
{
document.getElementById('poller_waitMessage').setStyle('display', 'block');
var ajax = new Ajax();
ajax.responseType = Ajax.FBML;
ajax.onerror = function(error)
{
new Dialog().showMessage("Error:", "Some communication error occured, Please reload the page.","Ok");
};
ajax.ondone = function(data)
{
document.getElementById('poller_waitMessage').setStyle('display', 'none');
document.getElementById(div_id).setInnerFBML(data);
}
ajax.requireLogin = true; // <----- this is important
ajax.post(url);
}
I've been happily using the form variable fb_sig_profile_user for previous apps, and when developing a new app last week, the variable was no where to be found.
Searched for several days, I was about to give up, and then the found answer:
ajax.requireLogin = true;
I understand FB cares about privacy and all, but they really need to announce these kinds of changes before just taking it away.
Million Thanks!