Link Multiple accounts in Firebase - javascript

I have been stuck with this problem for a long time and i decided to post my problem here.
My problem is to merge the accounts (Facebook and Google) in Firebase. Independently sign-up with either one of them works fine.
At first when the user Sign-up with google and later with Facebook (that has the same email address with google) it throws and error. I managed to handle the error as you see on my code below but i don't know how to merge both accounts.
Here is what i have done so far:
facebookSignin: function() {
var self = this
firebase.auth().signInWithPopup(facebookProvider).then(function(result) {
var token = result.credential.accessToken;
var user = result.user;
self.registerProfile()
}).catch(function(error) {
var errorCode = error.code;
var errorMessage = error.message;
console.log("ERROR:" + error)
console.log("email is : " + error.email)
if (errorCode == 'auth/account-exists-with-different-credential') {
firebase.auth().fetchProvidersForEmail(error.email).then(providers => {
//providers returns this array -> ["google.com"]
console.log("Providers:" + providers)
console.log("Credential: " + JSON.stringify(error.credential))
firebase.auth().currentUser.link(error.credential).then(function(user) {
console.log("Account linking success", user);
});
}).catch(function(error){
console.log("error:" + error)
})
}
console.log("error code:" + error.code+ "error msg:" + error.message)
});
First i already Signed up with google
Now i want to login with Facebook with the same email address
I get the current-user null obviously because the user is not signed in, this is the error: error:TypeError: __WEBPACK_IMPORTED_MODULE_1_firebase___default.a.auth(...).currentUser is null .
I read the documentation about the merge part but still could not figure this out. https://firebase.google.com/docs/auth/web/account-linking#link-federated-auth-provider-credentials-to-a-user-account
I really appreciate the help.

After you fetchProvidersForEmail and figure out the existing Google user, you have to first login to that existing account:
firebase.auth().signInWithPopup(new firebase.auth.GoogleAuthProvider().setCustomParameters({login_hint: error.email})...
After that completes, you then:
firebase.auth().currentUser.linkWithCredential(error.credential)
So the user first has to verify ownership of the existing account before linking the Facebook account.

Related

All return values are undefined from Facebook log in button

After successfully log in, i try to get a few fields from the user.
All of them are undefined other than the name and ID. The pop up indeed ask those permission which I granted.
Read all posts here and non offered a solution that work other than using tokens(?) which I am not sure how, and never see in FB examples.
FB.login(
function(response) {
if (response.status === "connected") {
console.log("connected");
console.log("Access Token: " + response.authResponse.accessToken);
testAPI();
} else {
console.log("not connected");
}
},
{ scope: "email,user_age_range,user_friends" }
);
function testAPI() {
console.log("Welcome! Fetching your information.... ");
FB.api("/me", function(response) {
console.log("name: " + response.name);
console.log("email: " + response.email);
console.log("id: " + response.id);
console.log("friends: " + response.user_friends);
console.log("age: " + response.user_age_range);
console.log("end");
});
}
If I print response i get an error :
Uncaught ReferenceError: respond is not defined
To anyone who wonder, first, the way to read it is :
FB.api('/me', {fields: 'name,email'}, (response) => {
console.log('name: ' + response.name);
console.log('email: ' + response.email);
});
Second, a few points to notice:
Remove your app on your facebook profiles (under Apps) otherwise every time you test, FB will automatically grant access even if you wish to add more permissions.
Remove cache from your browser every new test because FB will keep the previous state and changes will not take effect.(sometimes, even updated deployments will not)
You should deploy your website, with me - local host is not working with FB because they require https.
Testing Facebook is a little bit hassle.

Google firebase web: User authentication and database write

I have just started with firebase for my webapp and here is my code and problem beneath.
<script src="https://www.gstatic.com/firebasejs/4.1.2/firebase.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.1.1/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.1.1/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.1.1/firebase-database.js"></script>
<script>
// Initialize Firebase
var config = {
...
};
firebase.initializeApp(config);
</script>
<script>
function handleSignUp() {
var email = document.getElementById('email').value;
var password = document.getElementById('password').value;
if (email.length < 4) {
alert('Please enter an email address.');
return;
}
if (password.length < 4) {
alert('Please enter a password.');
return;
}
firebase.auth().createUserWithEmailAndPassword(email, password).catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
if (errorCode == 'auth/weak-password') {
alert('The password is too weak.');
} else {
alert(errorMessage);
}
console.log(error);
});
}
function initApp() {
document.getElementById('quickstart-sign-up').addEventListener('click', handleSignUp, false);
}
window.onload = function() {
initApp();
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
console.log('yes');
I want data persistence in firebase database at this step.
} else {
console.log('no');
}
});
};
</script>
Problem is whenever I am refreshing my page, as the user is authenticated, console returns Yes (when I am adding the database push logic, data is being saved again and again whenever I am refreshing the page. I have tried moving the console.log OR database push to .onAuthStateChange to my initApp() and handleSignUp() functions as well. But to no avail.
As per firebase docs, I tried the below as well:
var user = firebase.auth().currentUser;
if (user) {
// User is signed in.
} else {
// No user is signed in.
}
However, this almost always returns a console.log as No. I am thinking that since it takes some time for the authentication to happen, the user check is skipping authentication and appearing as if No user is authenticated.
The ask is I want the user to be signed up (and automatically logged in which happens anyway with firebase) and user details (along with additional details which I am asking the user to fill in at Sign Up) to be saved in firebase database one time only. Any pointer would be appreciated here.
Think I got it. The use of then (promises):
firebase.auth().createUserWithEmailAndPassword(email, password).then(function() {
var user = firebase.auth().currentUser;
console.log(user.email);
}).catch(function(error)
As soon as user is created, the function will act (will do the data persistence in the database) and since it is not dependent on user auth'ed or not, along with unique emails, this step would never be repeated, hence single time data save in database. Had gone through the docs multiple times, somehow missed it. Apologies guys.

Parse.com on Signup User name already exists, code 142

Update: Solved, happens to be incorrect Cloud Code I wrote, see update #3
I am trying to make a signup for user using Parse.com API in Javascript.
Still with no success.
Basically I have a user field and a password field, and when hit signup button, tries to login but always I have the "Error Code: 142 :User name already exists, try login error from Parse api.
What is wrong with the code? (I previously used c# code and it was success)
Thanks in response.
function onSignupButtonClicked(button) {
event.preventDefault();
game_username = $("#loginUserText").val();
game_password = $("#loginPasswordText").val();
parseLogout(); // tried both logout earlier or put here..
var user = new Parse.User();
user.set("username", game_username);
user.set("password", game_password);
var progressCircle = showProgressCircle(); //some fullscreen progress
//also tried user.signup(null, {.. with no luck
Parse.User.signUp(game_username, game_password, {}, {
success: function(user) {
// Hooray! Let them use the app now.
//NOW LOGIN
login(game_username, game_password).then(function(result) {
console.log(result); // "Stuff worked!"
hideProgressCircle(progressCircle);
$("#loginButton").attr("disabled", true);
$("#logoutButton").attr("disabled", false);
$("#signupButton").attr("disabled", true);
game_manualLogin = true;
isLoggedIn = true;
}, function(err) {
hideProgressCircle(progressCircle);
console.log("loginPromise: " + err.message + " code: " + err.code); // Error: "It broke"
handleParseError(err);
});
},
error: function(user, error) {
// Show the error message somewhere and let the user try again.
hideProgressCircle(progressCircle);
handleParseError(error);
}
});
}
update:
Even basic Parse.com javascript returns 142.. here is the code, and my location is Istanbul/Turkey
function register() {
var user = new Parse.User();
user.set("username", "testop");
user.set("password", "testop");
user.set("email", "email#example.com");
// other fields can be set just like with Parse.Object
user.set("phone", "415-392-0202");
user.signUp(null, {
success: function(user) {
// Hooray! Let them use the app now.
console.log("testop register ok!");
},
error: function(user, error) {
// Show the error message somewhere and let the user try again.
alert("Error: " + error.code + " " + error.message);
}
});
}
This is the error I get to above updated code
Error:code: 142 :User name already exists, try login (Code is from Parse Javascript Signup
Update #2:
Even Rest API gives same error:
MacBook-Pro:~ gg$ curl -X POST \
> -H "X-Parse-Application-Id: MYAPPID" \
> -H "X-Parse-REST-API-Key: MYRESTAPIKET" \
> -H "X-Parse-Revocable-Session: 1" \
> -H "Content-Type: application/json" \
> -d '{"username":"testdude","password":"tesdude","phone":"415-392-0202"}' \
> https://api.parse.com/1/users
{"code":142,"error":"User name already exists, try login"}
MacBook-Pro:~ gg$
UPDATE #3:
After checking with 3 apis, found that problem was my fault.
I forgot a Cloud Code on user save, which was faulty as it did not check length of query length..
Parse.Cloud.beforeSave(Parse.User, function(request, response) {
var username = request.object.get("username");
var usernamequery = new Parse.Query(Parse.User);
usernamequery.equalTo("username", username);
usernamequery.find({
success: function()
{
--->>>should be checking length of query here <<<---
console.log("same user name found");
response.error("User name already exists, try login");
},
error: function(error)
{
console.log("ok unique user name continue save");
response.success("OK saving user");
}
});
});
You need two forms, one for signing up (as a new user) which calls Parse.User.signUp and a second form (for returning users) that calls Parse.User.logIn.
The problem is that you can only 'sign up' once with a username and password, after which you should 'login'. Also when you have got a success callback from Parse.User.signUp then the user is logged in and you don't have to call 'login'.
Something like this (where the two event listeners are triggered by two different buttons).
SIGNUP
function onSignupButtonClicked(button) {
event.preventDefault();
game_username = $("#loginUserText").val();
game_password = $("#loginPasswordText").val();
Parse.User.signUp(game_username, game_password, {}, {
success: function(user) {
// A new user has signed up and is now the Parse.User.current() user
// Do something
},
error: function(user, error) {
// Show the error message somewhere and let the user try again.
}
});
}
LOGIN
function onLoginButtonClicked(button) {
event.preventDefault();
game_username = $("#loginUserText").val();
game_password = $("#loginPasswordText").val();
Parse.User.logIn(game_username, game_password, {}, {
success: function(user) {
// An existing user has logged in and is now the Parse.User.current() user
// Do something
},
error: function(user, error) {
// Show the error message somewhere and let the user try again.
}
});
}
More info here: https://parse.com/docs/js_guide#users-signup

Regularly signed out when using firebase authWithPassword

I have a phonegap app on iOS using firebase for authentication. Logging in is done like so:
var afterLogin = function(error, authData) {
if (error) {
console.log(error);
messenger.error(error.message);
return;
}
$scope.loggedIn = $auth.check();
$scope.$apply();
$sync.sync();
messenger.success('Logged in');
};
$scope.doLogin = function() {
mixpanel.track('login');
if (!$scope.loginForm.email && !$scope.loginForm.password) {
messenger.error('Enter email and password then tap login');
return;
} else if (!$scope.loginForm.email) {
messenger.error('Enter your email then tap login');
return;
} else if (!$scope.loginForm.password) {
messenger.error('Enter your password then tap login');
return;
}
ref.authWithPassword({
email : $scope.loginForm.email,
password : $scope.loginForm.password
}, afterLogin);
}
I check a user's status like this:
check: function() {
var authData = ref.getAuth();
if (authData) {
mixpanel.identify(authData.uid);
mixpanel.people.set({
"$email": authData.password.email
});
}
return !!authData;
}
It works fine initially, but users get signed out and have to log in again after 12-24 hours of not using the app. Perhaps when the app is shunted out of memory? Obviously this is pretty frustrating, not sure what's causing this. The session length is set to 24 weeks, still having the problem.
Firebase version: 2.1.2
Angular: 1.3.6
Log of localStorage after authenticating with username and password:
Coming back a day later after being logged out:
Contents of the cookie (same logged in or not, no firebase stuff in there):
It's a parameter in Firebase.
Go on the Dashboard of the Firebase.
Click on "Login & Auth".
Then in the first paragraph, there is an input and select for the Session Length. You can choose how many hours/weekks, etc you want.

Facebook Javascript, How to detect if user is a fan of my facebook page? While on my site?

I have the following JS code.
The code's purpose is to first get the users facebook id, and then using FQL check that id against my page ID and make sure the user is a fan.
The problem I am running into is that the only time the code actually works is if i login with my own personal facebook profile. I think its because my profile and the FB.init appid are somehow linked?
Can someone take a look at this code and show me where I am going wrong?
My goal again is to use JS to first get the users id (thus their thumbnail image), and then cross reference that against my own facebook page to check and see if they are a fan. If they are a facebook fan, then I will probably give them a coupon or something.
Thanks in advance.
<script src="http://connect.facebook.net/en_US/all.js"></script>
//Connect to facebook with my app id..
FB.init({
appId:'135445813195028',
cookie:false,
status:true,
xfbml:true
});
//Check to see if user is actually CONNECTED???
FB.getLoginStatus(function(response) {
if (response.session) {
// USER IS CONNECTED
FB.api('/me', function(user) {
if (user != null) {
var image = document.getElementById('imagez');
image.src = 'http://graph.facebook.com/' + user.id + '/picture?type=large';
var name = document.getElementById('name');
name.innerHTML = user.name;
FBID = user.id;
console.log('Facebook ID:' + FBID);
//assemble an FQL query to see if the guy is a fan of our page...
myquery = 'SELECT uid FROM page_fan WHERE page_id = 126923080686340 AND uid = ' + FBID;
console.log('query = ' + myquery);
///Run FQL Query to see if user is a fan
FB.api({
method: 'fql.query',
query: myquery
}, function(resp) {
if (resp.length) {
var IsFan = true;
alert('You are A fan!')
console.log('Visitor is a fan');
//show coupon code...
} else {
alert('Signed into facebook, but Not a fan!');
var IsFan = false;
console.log('Visitor is not a fan');
//show like button...
//once like is clicked then refresh the page...
}
});
//END Run FQL Query to see if user is a fan
}
});
//Figure out if they are a fan...
} else {
// USER IS NOT CONNECTED
alert('NO USER session, user is not logged into facebook!!!');
}
});
The FB.getLoginStatus check to see if the user is connected to your application .. not to facebook.
But when the user is not connected to your application, the .status property can tell you the reason of the fail (if the user is not logged-in at all, or just to your app).
So the structure you should use is
FB.getLoginStatus(function(response) {
if(response.session) {
alert('connected to Application');
} else {
// no user session available, someone you dont know
if(response.status == "notConnected") {
// But user is logged into facebook
alert("Not connected to Application, but is logged in to Facebook");
} else {
// User is not logged into facebook
alert('Not logged in to facebook');
}
}
});
But you cannot access the ID of a user that has not authorized your Application.
Not through Javascript API.

Categories