facebook
Facebook Graph API In Opera
February 12, 2011
0

Note: I tested the issue and the solution using Windows Opera 11.01 build 1190 and confirmed the fix works.

The Problem

Calls to FB.api never executed their callbacks.
For instance, in this code, Firefox and Chrome prints:
window.fbAsyncInit (from line 4) and onGetLoginStatusResponse (from line 33), but Opera 11.01 only prints the window.fbAsyncInit.

<script>
window.fbAsyncInit = function()
{
alert("window.fbAsyncInit called");
FB.init({
appId : '165923983441659',
status : false, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});

FB.getLoginStatus(onGetLoginStatusResponse);

};

(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);
}());

function facebookLogin()
{
FB.login(onFacebookLoginStatus, {perms:'read_stream,publish_stream'});
}

/*
* Callback function for FB.getLoginStatus
*/
function onGetLoginStatusResponse(response)
{
alert("onGetLoginStatusResponse(), "
+ "nresponse.status="+response.status
+" nresponse.session="+response.session
+" nresponse.perms="+response.perms);
if (response.status=="connected" && response.session)
{
alert("You are all set.");
var loginButtonDiv=document.getElementById("fb-login-button-div");
loginButtonDiv.style.display="none";
var contentDiv=document.getElementById("user-is-authenticated");
contentDiv.innerHTML="User has been authenticated. The application is ready to use.";
}
else
{
facebookLogin();
}
}

Fixing It On Javascript

To use fix this, you need to use the Custom Channel URL (If you have previously used the Facebook Old Rest API, the channel method might remind you of the old days of xdreceiver):
– add channelUrl parameter when calling FB.init.
– create a file, call it channel.html containing this line:

<script src="http://connect.facebook.net/en_US/all.js"></script>

Notes:

  • Change http to https if your page is running on https.
  • The channel.html can be put in the same folder as your main html or it can be in a general location, such as in the home folder.
  • You can do browser check to make the change only effective in Opera (the channelUrl uses some bandwidth). For example, with jQuery 1.4.2, doing the browser check (line 7):
  • More information on the Facebook site: http://developers.facebook.com/docs/reference/javascript/fb.init/
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script><script>
    ......omitted....
    
    FB.Event.subscribe('auth.statusChange', onFacebookStatusChange);
    if ($.browser.opera)
    {
    alert("You are running Opera browser");
    FB.init({
    appId : '165923983441659',
    status : true, // check login status
    cookie : true, // enable cookies to allow the server to access the session
    xfbml : true, // parse XFBML
    channelUrl : 'http://www.example.com/channel.html'
    });
    }
    else
    {
    alert("You are running Non Opera browser");
    
    FB.init({
    appId : '165923983441659',
    status : true, // check login status
    cookie : true, // enable cookies to allow the server to access the session
    xfbml : true // parse XFBML
    });
    }
    </script>
    

Test page: https://www.permadi.com/tutorial/facebook-graph-api-login-example/opera.html

Getting facebook-actionscript-api 1.5working with Opera

In your html, do not call the FB.init, instead call FB.init through ActionScript, adding the channelUrl into the options parameter. Example:

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:fb="http://www.facebook.com/2008/fbml">
<head>
<!-- Include support librarys first -->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script>
<script type="text/javascript" src="http://connect.facebook.net/en_US/all.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>

<script type="text/javascript">
$('#ConnectDemo').append('<h1>You need at least Flash Player 9.0</h1>');
swfobject.embedSWF("Facebook-Open-Graph-Example-1.5.opera.swf?<? echo(time()) ?>",
"ConnectDemo", "550", "250", "9.0", null, null, null, {name:"ConnectDemo"});
</script>
</head>
<body>
<div id="fb-root"></div>
<div id="ConnectDemo"></div>
</body>
</html>

In the Action Script side, call the Facebook.init with the channelUrl:

Facebook.init(APP_ID, handleLogin,
{channelUrl : 'http://www.example.com/channel.html'});

One drawback with this is you do not get to check whether the user is logged in or not when the app loads. If you want to check the user login status, you can call com.facebook.graph.Facebook.getLoginStatus after the callback to handleLogin is called, which is shown below:

/**
* Asynchronous method to get the user's current session from Facebook.
*
* This method calls out to the underlying Javascript SDK
* to check what the current user's login status is.
* You can listen for a javscript event by using
* Facebook.addJSEventListener('auth.sessionChange', callback)
* @see http://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus
*
*/
public static function getLoginStatus():void {
getInstance().getLoginStatus();
}

Test page: https://www.permadi.com/tutorial/as3-open-graph-example-basic-1.5/opera.html?test

Make sure your browser does not block popups.