I'm totally confused about Facebook's dialog feed, sharer and like buttons (I'm a noob to Facebook and its jargon)
On my website, I would like the following
to have a button at the top of the page where people can share my site to their wall
to have a button on the the page where users can share their main homepage on my site to their wall
to have a button where users can share individual items of theirs (events) to their wall
I've read the sharer button is being phased out in preference to the Like button but I see a problem with the Like button. I think something can only be liked once. A user's event might want to be shared several times (to remind their Fb users of the event)
I've seen the BBC use the dialog feed button to post items to a wall and that looks okay but I couldn't get the popup to work.
my requirements are to have different links for each of the three scenarios I've mentioned, with a different description for each scenario but sharing my site's logo.
I've read so much that I'm now totally confused plus all the APIs that Fb has. It's just crazy (or that's how it seems to me)
If someone could help clear the fog with sound recommendations and some sample code for each button, I would be very grateful.
Thank you.
.
For what your talking about you would want to use the feed dialog. It's flexible enough that you just need to setup your links and pass in some variables. I don't see the feed dialog being phased out as you mentioned they serve different purposes. I think they push the like as it's easier to use and not as likely to be abused.
You'll need to register an application and make sure to initialize the Facebook javascript SDK before you call the below function. If you're having issues with your popup it's probably due to the fact your FB init process is having issues. I've added a second function I use to init Facebook. Both functions use jQuery so you might have to modify if you don't use it.
You can create a pretty generic function like this:
$.shareMe = function(myName, myLink, myPicture, myCaption ) {
FB.ui(
{
method: 'feed',
name: myName,
link: myLink,
picture: myPicture,
caption: myCaption
},
function(response) {
if (response && response.post_id) {
alert('Thanks for Sharing.');
} else {
alert('Post was not published.');
}
}
);
}
and for Facebook initialization:
$.initFacebook = function(options){
$('#fb-root').remove();
$('body').append('<div id="fb-root"></div>');
var settings = {
'appId' : null,
'callback' : null,
'channelUrl' : null,
'status' : true,
'cookie' : true,
'xfbml' : true
};
if ( options ) {
$.extend( settings, options );
}
if( typeof( xc_app_id ) == 'undefined' ) { window.xc_app_id = settings.appId; }
window.fbAsyncInit = function() {
if(settings.channelUrl==null) {
FB.init({appId: settings.appId, status: settings.status, cookie: settings.cookie, xfbml: settings.xfbml, oauth: true, authResponse: true });
} else {
settings.channelUrl=location.protocol+'//'+settings.channelUrl;
FB.init({appId: settings.appId, status: settings.status, cookie: settings.cookie, xfbml: settings.xfbml, oauth: true, authResponse: true, channelUrl: settings.channelUrl });
}
if(typeof settings.callback == 'function'){ settings.callback.call(this); }
};
(function() {
var e = document.createElement('script');
e.async = true;
e.src = '//connect.facebook.net/en_US/all.js';
document.getElementById('fb-root').appendChild(e);
}());
}
and to call it you just use $.initFacebook({appId,'yourAppId'}); There are other options there you can lookup in the docs if you need them.
Related
Documentation for Parse.FacebookUtils.init() states:
The status flag will be coerced to 'false' because it interferes with Parse Facebook integration. Call FB.getLoginStatus() explicitly if this behavior is required by your application.
Unfortunately, when I try to call FB.getLoginStatus(), I get TypeError: Cannot read property 'getLoginStatus' of undefined. Is there either a callback that I can use to know when FB is loaded, or some other way to check the login status of a user on page load?
It would help to see some code, it sounds like the SDK hasn't loaded when you call getLoginStatus().
Anyway this may help, I took Facebook's basic Login flow and added Parse around it. It checks when the DOM is loaded so you could use some of this logic also.
Simple Facebook Login test with Parse - view source
Hope this helps.
I ended up using promises to resolve FB after it's loaded.
var fbDeferred = $q.defer();
$window.fbAsyncInit = function() {
Parse.FacebookUtils.init({
appId : 'xxxxxx',
xfbml : true,
version : 'v2.2'
});
fbDeferred.resolve(FB);
};
var getFB = function(){
return fbDeferred.promise;
}
var getFBLoginStatus = function(){
return getFB().then(function(FB){
//**FB is now available**
FB.getLoginStatus(function(response) {
if (response.status !== 'connected'){
...
}else{
...
}
});
});
});
I'm trying to reveal content on my website only to people who like my facebook page. I've tried severall tutorials but none of them work. The closest I got was following this:
http://www.dejanlevec.com/2011/05/11/how-to-display-certain-page-content-only-to-users-who-have-liked-our-page-on-facebook/
I can get it to work if I first dislike the page and then like it on the facebook_test.php . Thus it doesn't detect if I already like the page.
I have done this with javascript before using FB.Event.subscribe and edge.create as described below:
<script type="text/javascript">
window.fbAsyncInit = function() {
FB.init({appId: 'APP_ID_HERE', status: true, cookie: true, xfbml: true});
FB.Event.subscribe('edge.create',
function (response) {
window.location = "http://redirectexamplehere.com";
});
FB.Event.subscribe('edge.create',
function (response) {
window.location = "http://redirectexamplehere.com";
});
};
(function() {
var e = document.createElement('script');
e.async = true;
e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
document.getElementById('fb-root').appendChild(e);
}());
//]]>
</script>
This way a user will be redirected to wherever you specify upon them liking the page. Remember to load the SDK first or it won't work.
Detecting if a user likes you on a website is a bit trickier than in a Facebook page. You'll need to setup a Facebook application and use that on your website and have the user authenticate using the app in addition to liking your page. Once you have that connection with the user you can test to see if they are logged in and have liked your page. At that point you can display different types of content.
The extra step of having to authenticate the user is probably why you don't see this implemented on too many websites.
The created the following web application:
http://www.web-allbum.com/
I also added it to the Chrome Web Store:
https://chrome.google.com/webstore/detail/idalgghcnjhmnbgbeebpdolhgdpbcplf
The problem is that when go to the Chrome Web Store and install this app the Facebook login windows hangs at a "XD Proxy" window. While the connect itself works, this blank window can confuse the users.
I did my research, and this seems to be a Chrome issue:
https://code.google.com/p/chromium/issues/detail?id=59285#c26
If you uninstall the app from Chrome, the problem disappears.
Is there any workaround for this problem?
Similar stackoverflow questions:
Facebook connect login window locking in Chrome
FB.login dialog does not close on Google Chrome
facebook connect blank pop up on chrome
https://stackoverflow.com/questions/4423718/blank-page-with-fb-connect-js-sdk-on-after-permission-request
This is my Facebook connect in case it helps:
FB.init({
appId : window.__FACEBOOK_APP_ID__,
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true, // parse XFBML
channelUrl : window.__MEDIA_URL__ + 'channel.html', // channel.html file
oauth : true // enable OAuth 2.0
});
FB.XD.Flash.init();
FB.XD._transport = "flash";
if (A.networks.facebook.connected) {
FB.getLoginStatus(function (response) {
// Stores the current user ID for later use
that.network_id = response.authResponse.userID;
if (!response.authResponse) {
// no user session available, someone you dont know
A.networks.facebook.connected = false;
}
callback();
});
}
else {
callback();
}
};
The Solution
Thanks to the reekogi reply I was able to workaround this issue. Here is the full implementation:
In order to avoid the XD Proxy problem, you have to connecte to Facebook without using the FB.login, this can be achieved by manually redirecting the user to Facebook page.
I had this login function in my code:
_facebook.connect_to_network = function (callback) {
FB.login(function (response) {
if (response.authResponse) {
console.log('Welcome! Fetching your information.... ');
FB.api('/me', function (response) {
// Stores the current user Id for later use
that.network_id = response.id;
console.log('Good to see you, ' + response.name + '.');
callback();
});
}
else {
console.log('User cancelled login or did not fully authorize.');
that.connected = false;
callback();
}
}, {scope: window.__FACEBOOK_PERMS__});
};
Which I replaced by this code:
_facebook.connect_to_network = function (callback) {
var url = 'https://www.facebook.com/connect/uiserver.php?app_id=' + window.__FACEBOOK_APP_ID__ + '&method=permissions.request&display=page&next=' + encodeURIComponent(window.__BASE_URL__ + 'authorize-window?my_app=facebook&my_method=login') + '&response_type=token&fbconnect=1&perms=' + window.__FACEBOOK_PERMS__;
window.open(url);
};
The new code opens a popup which connects to Facebook and returns to the url specified in the 'next' parameter. I added some extra parameters in this callback url so that the javascript code could check for it and close the popup.
This code is executed when the Facebook redirects to the callback url:
_facebook.parse_url_params = function () {
// This is the popup window
if (URL_PARAMS.my_method === 'login') {
window.opener.A.networks.facebook.connected = true;
self.close();
}
};
URL_PARAMS is just a helper object that contains all the url parameters.
I still believe that this is a Chrome issue, but since this workaround has worked and solved my problem I am marking this question as solved.
Could you call a javascript redirect to get permissions then redirect back to the http://www.web-allbum.com/connected uri?
I described this method in detail here ->
Permissions on fan page
EDIT:
The method I demonstrated before will be deprecated when OAuth 2.0 comes into the requirements.
Here is the code, adapted for OAauth 2.0 (response.session is replaced with response.authResponse)
<div id="fb-root"></div>
<script>
theAppId = "YOURAPPID";
redirectUri = "YOURREDIRECTURI"; //This is the page that you redirect to after the user accepts the permissions dialogue
//Connect to JS SDK
FB.init({
appId : theAppId,
cookie: true,
xfbml: true,
status: true,
channelURL : 'http://yourdomain.co.uk/channel.html', // channel.html file
oauth : true // enable OAuth 2.0
});
//Append to JS SDK to div.fb-root
(function() {
var e = document.createElement('script');
e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
e.async = true;
document.getElementById('fb-root').appendChild(e);
}());
//Check login status and permissions
FB.getLoginStatus(function(response) {
if (response.authResponse) {
// logged in and connected user, someone you know
} else {
//Redirect to permissions dialogue
top.location="https://www.facebook.com/connect/uiserver.php?app_id=" + theAppId + "&method=permissions.request&display=page&next=" + redirectUri + "&response_type=token&fbconnect=1&perms=email,read_stream,publish_stream,offline_access";
}
});
</script>
Just tried and tested, worked fine in chrome.
I didn't try the solution proposed by Cesar, because I prefer to stick with Facebook's official javascript SDK.
Nevertheless I would like to add a few observations:
Indeed, the blocking problem only happened on Chrome after installing from Chrome Web Store. Uninstalling the web app solves the problem. (tested with legacy authentication method, without oauth 2.0). After closing the XD Proxy popup manually, my application was working properly.
After switching to asynchronous FB.init() and enabling oauth 2.0 option, my application would not even get a valid facebook connect status at login time ({authResponse: null, status: "unknown"})... Again, uninstalling it from the Chrome Web Store, it's working... ({authResponse: Object, status: "connected"})
No problem encountered with Safari, in any of these cases.
In IE8 - this can be caused by your flash version. I tried everything and nothing worked until I disabled flash. More details from this blog:http://hustoknow.blogspot.com/2011/06/how-facebooks-xdproxyphp-seemed-to-have.html#comment-form
Open a new browser tab in Chrome and see if you have the Facebook 'App' installed. If so, drag it to the bottom right corner to uninstall. Once uninstalled the XD Proxy will work.
Reference: facebook connect blank pop up on chrome
I was experiencing same problem for all browsers. When user clicked "login" button, a popup opened and hanged; and unless user killed browser process, it caused a high load on CPU. If user managed to see "allow" button and click it however, then it appeared a "xd proxy" blank window and nothing happened. That was the problem.
After long investigations, I noticed my new JS code which proxies setInterval/clearInterval/setTimeout/clearTimeout methods, caused this problem. Code is as follows:
window.timeoutList = new Array();
window.intervalList = new Array();
window.oldSetTimeout = window.setTimeout;
window.oldSetInterval = window.setInterval;
window.oldClearTimeout = window.clearTimeout;
window.oldClearInterval = window.clearInterval;
window.setTimeout = function(code, delay) {
window.timeoutList.push(window.oldSetTimeout(code, delay));
};
window.clearTimeout = function(id) {
var ind = window.timeoutList.indexOf(id);
if(ind >= 0) {
window.timeoutList.splice(ind, 1);
}
window.oldClearTimeout(id);
};
window.setInterval = function(code, delay) {
window.intervalList.push(window.oldSetInterval(code, delay));
};
window.clearInterval = function(id) {
var ind = window.intervalList.indexOf(id);
if(ind >= 0) {
window.intervalList.splice(ind, 1);
}
window.oldClearInterval(id);
};
window.clearAllTimeouts = function() {
for(var i in window.timeoutList) {
window.oldClearTimeout(window.timeoutList[i]);
}
window.timeoutList = new Array();
};
window.clearAllIntervals = function() {
for(var i in window.intervalList) {
window.oldClearInterval(window.intervalList[i]);
}
window.intervalList = new Array();
};
Removing these lines solved my problem. Maybe it helps to who experiences the same.
It appears this has been fixed in Chrome. No longer happens for us in Mac Chrome 15.0.874.106
Another workaround is to use this code after you call FB.init():
if (/chrome/.test(navigator.userAgent.toLowerCase())) {
FB.XD._origin = window.location.protocol + '//' + document.domain + '/' + FB.guid();
FB.XD.Flash.init();
FB.XD._transport = 'flash';
}
The pop-up window remains open and blank, but I found that in my Chrome Web Store app, the authentication goes through when this code is used.
This bug is also filed on Facebook Developers here: http://developers.facebook.com/bugs/278247488872084
I've been experiencing the same issue in IE9, and it seemed to stem from upgrading to Flash Player 10. The answers suggested already did not work for me and I'd lost hope in trying to fix it since finding an open bug at Facebook covering it. But Henson has posted an answer on a similar question that fixed it for me. In the JavaScript in my site master I removed the lines
FB.UIServer.setLoadedNode = function (a, b) {
//HACK: http://bugs.developers.facebook.net/show_bug.cgi?id=20168
FB.UIServer._loadedNodes[a.id] = b;
};
and now it works. (N.B. I have not checked to see if the IE8 issue those lines were intended to overcome returns.)
Via the Facebook javascript API, you can subscribe to the 'event.create' event to listen for when users "Like" something on a page via the Like Plugin. Is it possible to respond to the same user un-liking it as well? I don't see any events documented, wondering if this is a hidden feature.
You can now subscribe to the “edge.remove" event to know when a user unlikes a page. For example:
FB.Event.subscribe('edge.remove', function(href, widget) {
alert('You just unliked '+href);
});
Announcement: http://developers.facebook.com/blog/post/446/ documented at http://developers.facebook.com/docs/reference/javascript/FB.Event.subscribe
Recently added:
http://bugs.developers.facebook.net/show_bug.cgi?id=10796
The javascript sdk does not have an event for this. I have run into this problem before. The only way to check if a user has unliked an item is to do a Graph or Rest query to determine if they currently like the item.
Unfortunately "edge.remove" won't get triggered when you dislike a facebook-page via "liked"-button (on the top right) and click on "unlike". -.-
This event is very useful to create a vote system. The js-script below does an ajax-call to a PHP-page that updates a database.
var _paq = _paq || [];
FB.Event.subscribe('edge.create', function(response) {
var page = $("#pageid").val();
$.post("ajax_vote.php", { page: page },
function(data) {
//alert("voted : " + data);
});
});
FB.Event.subscribe('edge.remove', function(response) {
var page = $("#pageid").val();
$.post("ajax_unvote.php", { page: page },
function(data) {
//alert("unvoted : " + data);
});
});
I am trying to determine if a user is a facebook fan. I load the facebook JS library and initialize:
<script type="text/javascript" src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php/en_US"></script>
FB_RequireFeatures(["XFBML","Connect","Api"], function() { FB.init("my_api_key","xd_receiver.htm") });
FB.ensureInit(function () {
FB.ApiClient.pages_isFan(my_profile_id,"some_UID",callback);
});
However when I call the API client with FB.ApiClient.pages_isFan, I get a JS error -
FB.ApiClient is undefined
I am also using the FBML fan tag to display the "become a fan" button:
<fb:fan profile_id="my_profile_id" stream="0" connections="10" logobar="1" width="300"></fb:fan>
And would like to be notified when either the "become a fan" button is clicked or a user has successfully become a fan.
The business logic is pretty simple - If they become a fan, track it in my database. Then if they try to become a fan again, check with the library if they are a fan and say "You are already a fan" if they are a fan, show the widget if not.
Using the new JS SDK:
<fb:login-button perms="user_likes">
Grant Permissions to Allow access to Likes
</fb:login-button>
<button onclick="checkDoesLike()">Check if user Likes the Page</button>
<h1>Like this Application's Page</h1>
<fb:like-box profile-id="184484190795"></fb:like-box>
<script>
window.checkDoesLike = function() {
FB.api({ method: 'pages.isFan', page_id: '184484190795' }, function(resp) {
if (resp) {
Log.info('You like the Application.');
} else {
Log.error("You don't like the Application.");
}
});
};
</script>
A working example: http://fbrell.com/fb.api/does-like
Please note that #daaku's answer is true only in two cases:
If your app grant the user_likes permission or
The user's pages privacy setting is set to everyone.
Source:
Note: This call no longer requires a
session key. You must pass a user ID
if you don't pass a session key. If
the user's pages are set to less than
everyone privacy, you must ask the
user for the user_likes extended
permission and include a valid user
access token in the API call.
Try this code to better understand:
<button onclick="checkDoesLike()">Check if user Likes the Page (wrong way)</button>
<button onclick="checkDoesLike2()">Check if user Likes the Page (right way)</button>
<script>
window.checkDoesLike = function() {
FB.api({ method: 'pages.isFan', page_id: '184484190795', uid: '579187141' }, function(resp) {
if (resp) {
Log.info('579187141 likes the Application.');
} else {
Log.error("579187141 doesn't like the Application.");
}
});
};
window.checkDoesLike2 = function() {
FB.api({ method: 'pages.isFan', page_id: '184484190795', uid: '579187141' }, function(resp) {
if (resp == true) {
Log.info('579187141 likes the Application.');
} else if(resp.error_code) {
Log.error(resp.error_msg);
} else {
Log.error("579187141 doesn't like the Application.");
}
});
};
</script>
Working example.
I've also written a full tutorial about this today.
not sure if this is helpful at all, but I inspected the DOM with firebug and I found that it has moved onto the Facebook object
var pageID = 'your page';
var uid = FB.Facebook.apiClient.get_session().uid;
FB.Facebook.apiClient.pages_isFan(pageID, uid, function(result){ alert("boo!");});