Is it possible to delete facebook permission, after login prompt? - javascript

I have continue with facebook button in the user's profile page.
that opens facebook's permission page and saves facebook user ID to our DB, that makes a pair with his account.
Now I want to makedisconnect button that sends permission delete requests to facebook and delete entry from our DB.
I used FB.Event.subscribe('auth.authResponseChange', event); listener but the authResponse doesn't change when the user logs off from FB, on the other web browser tab.
if(fb_status === "connected" && fb_userID.length > 0){
removeFbUser(fb_userID); // deletion in DB
}else if (fb_status === 'not_authorized'){
//error message
}else{
// user is logged out
FB.login(function(response) {
if(response.status === "connected"){
removeFbUser(response.authResponse.userID);
fb_userID = response.authResponse.userID;
}else{
// error
}
fb_status = response.status;
});
}
I'm also getting this error message from facebook sdk :
You are overriding current access token, that means some other app is expecting different access token and you will probably break things. Please consider passing access_token directly to API parameters instead of overriding the global settings.

Related

How to send Facebook authentication details to Firebase using a Cordova plugin & Firebase template

Sorry this question is kind of long, it's because I've been trying to solve this problem for a while and want to make sure I don't leave any info out. I'm building a Cordova app and using Firebase for the authentication/database back end. I've been trying to authenticate users into Firebase using a Log in with Facebook button for almost a week now, but I haven't been able to get it to work.
Originally I tried following Firebase's example here: https://firebase.google.com/docs/auth/web/facebook-login (I need to use the "Advanced: Handle the sign in flow manually" as it is a Cordova Android & iOS app), this example didn't work for me as the link to Facebook's SDK script (//connect.facebook.net/en_US/sdk.js) kept throwing the error:
file://connect.facebook.net/en_US/sdk.js Failed to load resource: net::ERR_FILE_NOT_FOUND
I tried to fix this error in several ways, such as:
Changing it to https://connect.facebook.net/en_US/sdk.js (this resulted in the error: Can't Load URL: The domain of this URL isn't included in the app's domains. To be able to load this URL, add all domains and subdomains of your app to the App Domains field in your app settings. )
Added the links in question to the list of "Valid OAuth redirect URIs" and domains in the Facebook app settings
Storing the file in my local file system (and locally inside the app on my phone)
Including the entire SDK inside the head of my index.html file
None of these attempts worked. So instead I decided to use the plugin cordova-plugin-facebook from here: https://github.com/bisrael/cordova-plugin-facebook
This is the code I'm using to get the user's information from Facebook with the plugin:
function logInWithFacebook(){
CordovaFacebook.login({
onSuccess: function(result) {
console.log(result);
console.log(result.authToken);
// Store or send the user auth/access key here?
// Get user's name
retrieveUserDetails();
if(result.declined.length > 0) {
alert("The User declined something!");
}
},
onFailure: function(result) {
if(result.cancelled) {
alert("The user doesn't like my app");
} else if(result.error) {
alert("There was an error:" + result.errorLocalized);
}
}
});
}
function retrieveUserDetails(){
// Now that the user has authroised the app, make request to CordovaFacebook plugin to get user's name
CordovaFacebook.graphRequest({
path: '/me',
params: { fields: 'name' },
onSuccess: function (userData) {
console.log(userData);
console.log(userData.name);
// Here somehow send the retrieved username and send it to the Firebase function so that it's linked with the auth key.
},
onFailure: function (result) {
if (result.error) {
Error.log('error', 'There was an error in graph request:' + result.errorLocalized);
}
}
});
}
I'm now able to click on a log in button and log in successfully through Facebook. That process is returning a user auth/access key and the user's name from Facebook.
As I understand it, the manual log in flow example in Firebase's docs (https://firebase.google.com/docs/auth/web/facebook-login) takes the key returned from Facebook, converts it into a Firebase key, and then enters the user's newly created Firebase key and their username into Firebase's servers.
This seems pretty straight forward in the following sample code:
function checkLoginState(event) {
if (event.authResponse) {
// User is signed-in Facebook.
var unsubscribe = firebase.auth().onAuthStateChanged(function(firebaseUser) {
unsubscribe();
// Check if we are already signed-in Firebase with the correct user.
if (!isUserEqual(event.authResponse, firebaseUser)) {
// Build Firebase credential with the Facebook auth token.
var credential = firebase.auth.FacebookAuthProvider.credential(
event.authResponse.accessToken);
// Sign in with the credential from the Facebook user.
firebase.auth().signInWithCredential(credential).catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
// The email of the user's account used.
var email = error.email;
// The firebase.auth.AuthCredential type that was used.
var credential = error.credential;
// ...
});
} else {
// User is already signed-in Firebase with the correct user.
}
});
} else {
// User is signed-out of Facebook.
firebase.auth().signOut();
}
}
function isUserEqual(facebookAuthResponse, firebaseUser) {
if (firebaseUser) {
var providerData = firebaseUser.providerData;
for (var i = 0; i < providerData.length; i++) {
if (providerData[i].providerId === firebase.auth.FacebookAuthProvider.PROVIDER_ID &&
providerData[i].uid === facebookAuthResponse.userID) {
// We don't need to re-auth the Firebase connection.
return true;
}
}
}
return false;
}
FB.Event.subscribe('auth.authResponseChange', checkLoginState);
My question is, how can I send the auth key and username returned from the Cordova plugin code, to Firebase's example code so that it works smoothly?
Firebase's example code includes this listener which listens for any change in the Facebook authorization status: FB.Event.subscribe('auth.authResponseChange', checkLoginState); but as this uses Facebook's SDK it won't work with my current set up.
I'm using the following Firebase chat app as a template to work from: https://gist.github.com/puf/8f67d3376d80ed2d02670d20bfc4ec7d as you can see it has a Login with Facebook button, but no code for handling the process, I'm trying to apply parts of the manual log in flow example in Firebase's docs (https://firebase.google.com/docs/auth/web/facebook-login) with data returned from the cordova-plugin-facebook queries, and integrate both with Firebase's chat app template.
I'm really at a loss as to what to do next, I've tried everything I can think of. Any help in solving this problem would be really, really appreciated.
Thank you in advance!
UPDATE
Questions and answers:
How does it work at the moment?
Right now I have a "Facebook Login" button - when this is clicked it runs logInWithFacebook(). This function uses the CordovaFacebook plugin, it also runs the function retrieveUserDetails() after the user signs in with Facebook. retrieveUserDetails() gets some user info from Facebook which I hope to then insert into my Firebase database.
logInWithFacebook() works correctly (it opens up a Facebook login page, and when the user logs in, I'm able to console.log the user's Facebook ID, and the Facebook access Token.
retrieveUserDetails() also works correctly (I'm able to console.log the user's name taken from Facebook).
How do you want it to work?
I'm happy with how the first half of the process is working (the logging in with Facebook and retrieving user details is working correctly). However I want this log in to trigger Firebase's auth state change listener, so that Firebase detects and confirms that the user has logged in:
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
console.log("User is signed in.");
} else {
console.log("User is not signed in.");
}
});
What is not working the way you want?
The first half of the process is working correctly, but I'm lost when it comes to what to do with the accessToken returned from Facebook. From reading the docs I think that Firebase is supposed to convert this token into a Firebase access token, and then that is used to log the user into Firebase (this would also trigger the above AuthStateChanged function). From there I want to be able to insert any data I've retrieved from Facebook (the user's name etc) into my Firebase database. But the main problem is getting the Facebook accessToken converted into a Firebase login (the second block of code in my original question is where I'm trying to perform the conversion/sign into Firebase).
Because I'm using Cordova, this method (logging into Facebook with a plugin and then handling the conversion of the accessToken) seems to be the only way to log in with Facebook. But I'm totally lost on how to complete the second half.
UPDATE 2
I've trimmed parts from the sample convert-Facebook-token-to-Firebase-token code from the docs so that the Facebook SDK isn't required. And it appears to be working. This is the code after cutting away the SDK related parts:
// First, define the Facebook accessToken:
var FBaccessToken = result.accessToken;
// Build Firebase credential with the Facebook auth token.
var credential = firebase.auth.FacebookAuthProvider.credential(
FBaccessToken);
// Sign in with the credential from the Facebook user.
firebase.auth().signInWithCredential(credential).then(function(user){
console.log("It looks like we signed into Firebase with the Facebook token correctly.");
}, function(error) {
console.log("Something went wrong, user isn't signed into Firebase with the FB token.");
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
// The email of the user's account used.
var email = error.email;
// The firebase.auth.AuthCredential type that was used.
var credential = error.credential;
// ...
});
I still need to add the user's email from Facebook and try to send that while logging into Firebase too - so that I'll have some identifier for the user in the Firebase console, but this is a good start.
2nd UPDATE
The below code successfully gets user data from Facebook after the user authorizes the app:
CordovaFacebook.graphRequest({
path: '/me',
params: { fields: 'first_name,last_name,email,locale,gender,age_range,picture.width(200).height(200)' },
onSuccess: function (userData) {
console.log(userData)
var first_name = userData.first_name;
var last_name = userData.last_name;
var email = userData.email;
var locale = userData.locale;
var gender = userData.gender;
var min_age = userData.age_range.min;
var profile_picture = userData.picture.data.url;
// Enter user details into the Firebase database:
firebase.database().ref('users/' + uid).set({
first_name: first_name,
last_name: last_name,
email: email,
locale: locale,
gender: gender,
min_age: min_age,
profile_picture : profile_picture
});
console.log("Facebook user data should now be in the database!");
},
onFailure: function (result) {
if (result.error) {
Error.log('error', 'There was an error in graph request:' + result.errorLocalized);
}
}
});
(Just an answer to the last update, as you figured out the rest :))
How to get user email from CordovaFacebook.login()
Looking at the CordovaFacebook documentation you can add a permissions property on the object passed to the login method.
According to the Facebook API documentation the permission name for email is just "email".
I haven't tested, but I think this should work:
CordovaFacebook.login({
permissions: [ 'email' ],
onSuccess: function(result) {
console.log('email:', result.email);
...
},
onFailure: function(result) {
...
}
});

Facebook fails to redirect to application URL after login

I am creating facebook application. If user is not logged on facebook I redirect them to FaceBook login that redirects to my application URL after they logged to facebook. Problem is that user is redirected to facebook.com insted of facebook application URL
Here is code that I am using to check if user logged to FaceBook
function statusChangeCallback(response) {
if (response.status === 'connected') {
// Logged into your app and Facebook.
FillInfo();
} else if (response.status === 'not_authorized') {
window.top.location("https://apps.facebook.com/memorygameonfb/?fb_source=bookmark&ref=bookmarks&count=0&fb_bmpos=3_0")
} else {
// The person is not logged into Facebook, so we're not sure if
// they are logged into this app or not.
window.top.location = "https://www.facebook.com/login.php?api_key=id&skip_api_login=1&display=page&redirect_uri=https://apps.facebook.com/memorygameonfb/?fb_source=bookmark&ref=bookmarks&count=0&fb_bmpos=3_0"; }
}
The reason they are being redircted to facebook.com is becasue that is where you are sending them
You need to create $params so when your user logs in you can redirect them to your app.
You can find the dox on this Here
$params = array(
'scope' => 'read_stream, friends_likes',
'redirect_uri' => 'https://www.myapp.com/post_login_page' //This redirects to ur APP!
);
$loginUrl = $facebook->getLoginUrl($params);
I personally am not great with JS I use php for facebook api I think it is easier to manage then the JS API
If you would like to download a basic app allowing you to login with php
Click Here
and follow the readme file for instructions.

FB.getLoginStatus() return "unknown" in Firefox when user is logged

In my site I test if a user is logged on Facebook in order to suggest him/her to like my Facebook site page.
Then, I use the conventional Facebook Js SDK function to understand if the user is logged or not:
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
var accessToken = response.authResponse.accessToken;
fbuid = response.authResponse.userID;
status = 'connected';
} else if (response.status === 'not_authorized') {
fbuid = null;
status = 'not_authorized';
} else { // the user isn't logged in to Facebook.
status = 'generic';
fbuid = 1;
}
that.evaluateFbStatus(status, fbuid);
}
It works perfectly with every browsers except Firefox.
In Firefox it returns always unknown even if the user is logged on Facebook and the status is not_authorized or connected.
Any help is accepted.
The problem is due to third party cookies.
To use Facebook SDK functions in Firefox, is necessary to open setting and able third party cookies Preferences > Privacy > Accept-third-party cookies
Have a look on this page for more details.

Facebook error when like button pressed

I get this, when clicking on the like button.
Unsafe JavaScript attempt to access frame with URL http://www.facebook.com/dialog/oauth?api_key=248753205242460&app_id=248753205242460&channel_url=http%3A%2F%2Fstatic.ak.facebook.com%2Fconnect%2Fxd_arbiter.php%3Fversion%3D9%23cb%3Dfedecb848%26origin%3Dhttp%253A%252F%252Flocalhost%252Ff2ad19772%26domain%3Dlocalhost%26relation%3Dparent.parent&client_id=248753205242460&display=none&domain=localhost&locale=en_US&origin=1&redirect_uri=http%3A%2F%2Fstatic.ak.facebook.com%2Fconnect%2Fxd_arbiter.php%3Fversion%3D9%23cb%3Df99e53428%26origin%3Dhttp%253A%252F%252Flocalhost%252Ff2ad19772%26domain%3Dlocalhost%26relation%3Dparent%26frame%3Df2c40b1914&response_type=token%2Csigned_request%2Ccode&sdk=joey from frame with URL http://www.facebook.com/plugins/like.php?action=like&api_key=248753205242460&channel_url=http%3A%2F%2Fstatic.ak.facebook.com%2Fconnect%2Fxd_arbiter.php%3Fversion%3D9%23cb%3Df458cef1c%26origin%3Dhttp%253A%252F%252Flocalhost%252Ff2ad19772%26domain%3Dlocalhost%26relation%3Dparent.parent&colorscheme=light&extended_social_context=false&font=segoe%20ui&href=http%3A%2F%2Fecommercedeveloper.com&layout=standard&locale=en_US&node_type=link&sdk=joey&show_faces=true&width=400#. Domains, protocols and ports must match.
Unsafe JavaScript attempt to access frame with URL https://s-static.ak.facebook.com/connect/xd_arbiter.php?version=9#channel=f2ad19772&origin=http%3A%2F%2Flocalhost&channel_path=%2FDummy%2FFBplugin%2Ffb.php%3Ffb_xd_fragment%23xd_sig%3Dfe951f208%26 from frame with URL http://www.facebook.com/plugins/like.php?action=like&api_key=248753205242460&channel_url=http%3A%2F%2Fstatic.ak.facebook.com%2Fconnect%2Fxd_arbiter.php%3Fversion%3D9%23cb%3Df458cef1c%26origin%3Dhttp%253A%252F%252Flocalhost%252Ff2ad19772%26domain%3Dlocalhost%26relation%3Dparent.parent&colorscheme=light&extended_social_context=false&font=segoe%20ui&href=http%3A%2F%2Fecommercedeveloper.com&layout=standard&locale=en_US&node_type=link&sdk=joey&show_faces=true&width=400#. Domains, protocols and ports must match.
I dont know why I get that error, it could be because the code that checks the login is triggered..
This my html:
<!DOCTYPE html>
<body>
<div id="fb-root"></div>
<script type="text/javascript">
$(document).ready(function(){
FB.init({
appId : '248753205242460', // App ID
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
window.fbAsyncInit = function() {
console.log('Sdk is loaded');
FB.getLoginStatus(function(response) {
console.log('GEtting logged in status');
if (response.status === 'connected') {
// the user is logged in and has authenticated your
// app, and response.authResponse supplies
// the user's ID, a valid access token, a signed
// request, and the time the access token
// and signed request each expire
var uid = response.authResponse.userID;
console.log('User is connected');
var accessToken = response.authResponse.accessToken;
} else if (response.status === 'not_authorized') {
// the user is logged in to Facebook,
// but has not authenticated your app
console.log('User not authorized');
} else {
// the user isn't logged in to Facebook.
console.log('User inst logged in');
}
});
};
FB.Event.subscribe('edge.create',
function(response) {
console.log('You liked the URL: ' + response.status);
});
});
</script>
</body>
</html>
The error messages Unsafe JavaScript attempt to access frame with URL and Domains, protocols and ports must match usually imply that your http protocols are faulty.
Should you be using HTTPS for these calls instead of normal HTTP?
when i see these errors i usually test out if i'm missing an https somewhere...
Also see if your app has all it's secure URLs set up in the developer management panel on facebook!
The other event that I am using is "getLoginStatus", which will show me if the user is logged in to facebook or not..
That’s not an “event” in itself – it’s just an asynchronous method, and it gets you the login status.
console.log('FB.getLoginStatus: '+FB.getLoginStatus);
At this point you are not even calling the method – you are just stating it’s name. (I know, you’re calling it before – but this debug output does not make much sense.)
I want to trigger edge.create
How exactly did you implement your like button? This event is not fired if you’re using the iframe version of the button.
[from comments] I think I need to have my own app id... can it be the cause? it is my facebook name and not a number
Of course you do. Your user name is not an app id in any way.

Get facebook app install timestamp

How can I get using the JS api only the install time of the currently used facebook application?
In general I would like to verify that the user that currently online is a new user and not already registered returning user.
You can use FB.getLoginStatus as recomended here it can tell you weather visitor are logged into facebook and if so if they are registered with your application.
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
// the user is logged in and has authenticated your
// app, and response.authResponse supplies
// the user's ID, a valid access token, a signed
// request, and the time the access token
// and signed request each expire
var uid = response.authResponse.userID;
var accessToken = response.authResponse.accessToken;
} else if (response.status === 'not_authorized') {
// the user is logged in to Facebook,
// but has not authenticated your app
} else {
// the user isn't logged in to Facebook.
}
});

Categories