Sign in user if is register (Firebase facebook/google auth) - javascript

i´m want to check if the user who want to sign in using the facebook or google auth in to my web app is register on the real time database of firebase, so the idea is after the user press the button of sign in with facebook/google, first check in to the real time database if the uid is already on the real time database before redirect the user to another URL, for this i´m using the next function:
app.auth = function(){
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
var users_ref = firebase.database().ref('dream_wedding_users');
var register_user;
var register = false;
users_ref.on('value', function(snapshot) {
register_user = snapshot.val();
});
$.each(register_user, function(index, val){
if(user.uid === index){
register = true;
}
})
if(!register){
firebase.auth().signOut();
$('#login').modal('hide');
$('#modal_register').modal('show');
return false;
}else{
$(window).attr('location', 'http://localhost/wedding/en/gallery_en.php');
}
}
});
}
and for the auth function just the regular auth function for facebook and google that attach to a button.
app.facebook_login = function(){
var provider = new firebase.auth.FacebookAuthProvider();
firebase.auth().signInWithPopup(provider).then(function(result) {
// This gives you a Facebook Access Token. You can use it to access the Facebook API.
var token = result.credential.accessToken;
// The signed-in user info.
var user = result.user;
// ...
}).catch(function(error) {
console.log(error)
});
}
app.google_login = function(){
var provider = new firebase.auth.GoogleAuthProvider();
firebase.auth().signInWithPopup(provider).then(function(result) {
// This gives you a Google Access Token. You can use it to access the Google API.
var token = result.credential.accessToken;
// The signed-in user info.
var user = result.user;
// ...
firebase.auth().signInWithRedirect(provider);
}).catch(function(error) {
console.log(error);
});
}
my problem is the next one, when i click sign in facebook or google, first login the user, then redirect the user, then check is the user is register on the real time data base and then logout the user if is not register and then show the modal. i don´t want that redirect the user i want that check if the user is register and then show the modal of "register" if the user is not register without redirect, and redirect if the user is register.

You want to add a unique user , if it is already not registered right ?
here is the valid way:
var usernew = result.additionalUserInfo.isNewUser
console.log('Is this a new user ? => ' + usernew );
complete code is as follows:
var provider = new firebase.auth.GoogleAuthProvider();
firebase.auth().signInWithPopup(provider).then(function(result){
var usernew = result.additionalUserInfo.isNewUser;
console.log('Is this a new user ? => ' + usernew );
if (usernew == true) {
NewUser();
}
var token = result.credential.accessToken;
user = result.user;
// alert(JSON.stringify(user.photoURL))
}).catch(function(error) {
var errorCode = error.code;
var errorMessage = error.message;
var email = error.email;
var credential = error.credential;
});
add user if it is not registered:
function NewUser(){
firebase.database().ref('/users').push({
Name : 'Johnson'
Age : '22'
})
}

Related

How to Retrieve User UID After They Have Been Created Firebase JS

I am trying to retrieve the UID of a user I just created in Firebase using JavaScript. Below is my current code:
firebase.auth().createUserWithEmailAndPassword(email, pass).catch(function(error, data) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
newusercreateduuid = data.user.uid;
// ...
console.log(errorCode + ' Error Message: ' + errorMessage);
});
I have tried a variety of callbacks including userData, data, user, and many more, but they all return null. I cannot seem to find anything online. I did find another Stack Overflow post using userData, but that returned null for me. How can I retrieve the UID of the user I just created?
you need to add this:
You can access to the then method:
firebase.auth()
.createUserWithEmailAndPassword(email, password)
.then(function(user)
// user information is available here...
})
.catch(function(error, data) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
newusercreateduuid = data.user.uid;
// ...
console.log(errorCode + ' Error Message: ' + errorMessage);
});
Also, if you need to control the user log changes, you can do this:
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
var displayName = user.displayName;
var email = user.email;
var emailVerified = user.emailVerified;
var photoURL = user.photoURL;
var isAnonymous = user.isAnonymous;
var uid = user.uid;
var providerData = user.providerData;
// ...
} else {
// User is signed out.
// ...
}
});
This will give you the user state after login. Source

Sign Up problem in react native (about concurrency)

Hey I am doing a sign up form, where every time the username textinput is changed, I look at my DB if it is available or not (to change the icon color of the text input to red or green).
const checkUsername = async () => {
// Get username from input
const username = usernameInput.current.props.value;
let isUsernameAvailable = false;
if (!isEmpty(username)) {
const { firebase } = props;
// Check if the username is available on the database and valid
isUsernameAvailable =
(await firebase.checkUsername(username)) && validateUsername(username);
}
setIsUsernameAvailable(isUsernameAvailable);
};
I have my own firebase rules to create a username only if not exists, but sometimes, when I write really fast the input and click on the submit button, a user with a not available username is created.
This is the submit function:
const signUp = async () => {
// Do not try to sign up again if the user is currently signing up
if (isLoading) return;
const { firebase, toast } = props;
const username = usernameInput.current.props.value;
const email = emailInput.current.props.value;
const password = passwordInput.current.props.value;
const repeatPassword = repeatPasswordInput.current.props.value;
// It is too important to check that the username is not taken
await checkUsername(username);
const formError = validateForm(username, email, password, repeatPassword);
// Do not sign up if the form is incorrect
if (formError) {
// Show error message
toast.current.show(formError, 3500);
return;
}
// Start loading
setIsLoading(true);
// Try to create the user with the email and password
firebase
.createUserWithEmailAndPassword(email, password)
.then((currentUser) => {
// Get the username from the input
const username = usernameInput.current.props.value;
// Create a user with this username and the current user uid in the db
firebase.createUserWithUsername(username, currentUser.user.uid);
})
.catch((err) => {
if (err.code !== "auth/too-many-request") {
// Convert error code to message
const message = firebase.parseError(err.code);
// Show error message
toast.current.show(message, 3500);
// Finish loading
setIsLoading(false);
}
});
/*
Pd: It has no sense to make a query if the username, email and password
are not valid. We avoid making extra queries.
*/
};
Any ideas?

Retrieving Firebase Child Value in Javascript

function sontinue() {
var user = firebase.auth().currentUser;
var uid = user.uid;
var adaRef = firebase.database().ref("User/" + uid);
if (adaRef.orderByChild("Role").equalTo("admin")) {
location.href = "DB.html";
} else {
location.href = "index.html";
}
}
I would like to link my "admin" account to DB.html and "user" account to index.html but i think i always failed in Retrieving the Child Value.
You're not retrieving the data from the server. Remember you need to call .once('value') to get your query and then iterate through the remaining code based onw hether their value is of admin or user. Firebase Docs has more explination I've amended your code and put it below
function sontinue() {
var user = firebase.auth().currentUser;
var uid = user.uid;
var adaRef = firebase.database().ref("User/" + uid).orderByChild("Role");
//you now need to retrieve the data
return adaRef.once('value').then((snapshot)=>{
return snapshot.forEach(snapshot=>{
if (snapshot.child("Role").val()==="admin") {
location.href = "DB.html";
} else {
location.href = "index.html";
}
return console.log("added");
})
})
}
If you just wanted to find out who was of the user type admin...i'd use this below...much more efficient.
function sontinue() {
var user = firebase.auth().currentUser;
var uid = user.uid;
var adaRef = firebase.database().ref("User/" + uid).orderByChild("Role").equalTo("admin");
//you now need to retrieve the data
return adaRef.once('value').then((snapshot)=>{
//you now have all the users that are just admins
return snapshot.forEach(snapshot=>{
location.href = "DB.html";
return console.log("added");
})
})
}

how to automatic go to athor page, when success create account and set value at firebase database

i want make system, after success create an account and set value on Firebase database, it will go to the other page. i has set go to next page but, not set value into database. the think is, i want to make sure after create and set value to database and the system will move to another page.
var email = document.getElementById("email_field");
var password = document.getElementById("password_field");
firebase.auth().createUserWithEmailAndPassword(email.value, password.value).then(function(user)
{
var user = firebase.auth().currentUser;
if (firebase.auth().currentUser !== null)
console.log("user id: " + firebase.auth().currentUser.uid);
LogUser(user.uid);
console.log("user id: " + user.uid);
}).catch(function(error) {
var errorCode = error.code;
var errorMessage = error.message;
window.alert("Error : " + errorCode+"message"+errorMessage);
if(err = null){
}
// ...
});
function LogUser(user){
firebase.database().ref('tbluser').child(user).set({
email: email,
test:"ha"
});
location.replace("signin.html")
}
}
Check out the article here on how to use Firebase Database callbacks.
Your code should look something like this:
firebase.database().ref('tbluser').child(user).set({
email: email,
test: "ha"
}, function(error) {
if (error) {
// it failed, do something here
} else {
// Data saved successfully!
location.replace("signin.html")
}
})
Good luck!

Linking Google account with existing account created using email in Parse.com

I have implemented google login in parse. Here is my code:
var querystring = require('querystring');
var _ = require('underscore');
var Buffer = require('buffer').Buffer;
var googleValidateEndpoint = 'https://www.googleapis.com/oauth2/v1/userinfo';
var TokenStorage = Parse.Object.extend("TokenStorage");
var restrictedAcl = new Parse.ACL();
restrictedAcl.setPublicReadAccess(false);
restrictedAcl.setPublicWriteAccess(false);
Parse.Cloud.define('accessGoogleUser', function(req, res) {
var data = req.params;
var token = data.code;
/**
* Validate that code and state have been passed in as query parameters.
* Render an error page if this is invalid.
*/
if (!(data && data.code)) {
res.error('Invalid auth response received.');
return;
}
Parse.Cloud.useMasterKey();
Parse.Promise.as().then(function() {
// Validate & Exchange the code parameter for an access token from Google
return getGoogleAccessToken(data.code);
}).then(function(httpResponse) {
var userData = httpResponse.data;
if (userData && userData.id) {
return upsertGoogleUser(token, userData, data.email);
} else {
return Parse.Promise.error("Unable to parse Google data");
}
}).then(function(user) {
/**
* Send back the session token in the response to be used with 'become/becomeInBackground' functions
*/
res.success(user.getSessionToken());
}, function(error) {
/**
* If the error is an object error (e.g. from a Parse function) convert it
* to a string for display to the user.
*/
if (error && error.code && error.error) {
error = error.code + ' ' + error.error;
}
res.error(JSON.stringify(error));
});
});
var getGoogleAccessToken = function(code) {
var body = querystring.stringify({
access_token: code
});
return Parse.Cloud.httpRequest({
url: googleValidateEndpoint + '?access_token=' + code
});
}
var upsertGoogleUser = function(accessToken, googleData, emailId) {
var query = new Parse.Query(TokenStorage);
query.equalTo('accountId', googleData.id);
//query.ascending('createdAt');
// Check if this googleId has previously logged in, using the master key
return query.first({ useMasterKey: true }).then(function(tokenData) {
// If not, create a new user.
if (!tokenData) {
return newGoogleUser(accessToken, googleData, emailId);
}
// If found, fetch the user.
var user = tokenData.get('user');
return user.fetch({ useMasterKey: true }).then(function(user) {
// Update the access_token if it is different.
if (accessToken !== tokenData.get('accessToken')) {
tokenData.set('accessToken', accessToken);
}
/**
* This save will not use an API request if the token was not changed.
* e.g. when a new user is created and upsert is called again.
*/
return tokenData.save(null, { useMasterKey: true });
}).then(function(obj) {
// Reset password
password = new Buffer(24);
_.times(24, function(i) {
password.set(i, _.random(0, 255));
});
password = password.toString('base64')
user.setPassword(password);
return user.save();
}).then(function(user) {
// ReLogin
// This line is what I am talking about
return Parse.User.logIn(user.get('username'), password);
}).then(function(obj) {
// Return the user object.
return Parse.Promise.as(obj);
});
});
}
var newGoogleUser = function(accessToken, googleData, email) {
var user = new Parse.User();
// Generate a random username and password.
var username = new Buffer(24);
var password = new Buffer(24);
_.times(24, function(i) {
username.set(i, _.random(0, 255));
password.set(i, _.random(0, 255));
});
var name = googleData.name;
// name = name.split(" ");
// var fullname = name;
// if(name.length > 1)
// var lastName = name[name.length-1];
user.set("username", username.toString('base64'));
user.set("password", password.toString('base64'));
user.set("email", email);
user.set("fullName", name);
// user.set("last_name", lastName);
user.set("accountType", 'google');
// Sign up the new User
return user.signUp().then(function(user) {
// create a new TokenStorage object to store the user+Google association.
var ts = new TokenStorage();
ts.set('user', user);
ts.set('accountId', googleData.id);
ts.set('accessToken', accessToken);
ts.setACL(restrictedAcl);
// Use the master key because TokenStorage objects should be protected.
return ts.save(null, { useMasterKey: true });
}).then(function(tokenStorage) {
return upsertGoogleUser(accessToken, googleData);
});
}
It works perfectly fine. Now the problem I am facing is that I want to link google account with an existing parse account created using email or username & password. The problem in doing so is that to login/signup using google I have to reset the password of the user to login so as to get the session token. See this line in the code -> [This line is what I am talking about]. So if I do so an existing user who had earlier used username/email & password to login won't be able to login again using email since I have reset his/her password. I have seen this and all the other links related to this but none of which solves this problem.
Can somebody here guide me in the right direction?
Log added as response to one of the comments:
{"accountType":"google","createdAt":"2016-01-07T17:30:57.429Z","email":"skdkaney#gmail.com","fullName":"ashdakhs basdkbney","updatedAt":"2016-01-07T17:30:57.429Z","username":"owt3h0ZZEZQ1K7if55W2oo3TBLfeWM6m","objectId":"lSlsdsZ9"}
Added upsert function as per comment request:
var upsertGoogleUser = function(accessToken, googleData, emailId) {
var query = new Parse.Query(TokenStorage);
query.equalTo('accountId', googleData.id);
//query.ascending('createdAt');
// Check if this googleId has previously logged in, using the master key
return query.first({ useMasterKey: true }).then(function(tokenData) {
// If not, create a new user.
if (!tokenData) {
return newGoogleUser(accessToken, googleData, emailId);
}
// If found, fetch the user.
var userw = tokenData.get('user');
var users_id = userw.id;
var query2 = new Parse.Query(Parse.User);
query2.equalTo('objectId',users_id);
// The new query added
return query2.first({ useMasterKey: true }).then(function(user) {
// Update the access_token if it is different.
// if (accessToken !== tokenData.get('accessToken')) {
// tokenData.set('accessToken', accessToken);
// }
console.log(user);
console.log("******");
/**
* This save will not use an API request if the token was not changed.
* e.g. when a new user is created and upsert is called again.
*/
// return tokenData.save(null, { useMasterKey: true });
}).then(function(obj) {
console.log(obj);
// console.log(user);
var result = user ;
// Return the user object.
return Parse.Promise.as(result); // this is the user object acquired above
});
After a discussion with OP, there are possible solutions to this matter but each of them have pros and cons.
Disabling Revocable Session
Since the introduction of Revocable Session, getSessionToken will always return undefined even with master key. To turn it off, go to App Settings >> Users >> Turn off Require revocable sessions.
Then, in upsertGoogleUser method, you just need to return the user object from tokenData.get('user'). It is enough to call user.getSessionToken() in your main cloud function. The final method should look like:
var upsertGoogleUser = function(accessToken, googleData, emailId) {
Parse.Cloud.useMasterKey();
var query = new Parse.Query(TokenStorage);
query.equalTo('accountId', googleData.id);
//query.ascending('createdAt');
// Check if this googleId has previously logged in, using the master key
return query.first().then(function(tokenData) {
// If not, create a new user.
if (!tokenData) {
return newGoogleUser(accessToken, googleData, emailId);
}
// If found, fetch the user.
var userw = tokenData.get('user');
var users_id = userw.id;
var query2 = new Parse.Query(Parse.User);
query2.equalTo('objectId',users_id);
return query2.first().then(function(user) {
console.log(user);
console.log(user.getSessionToken());
console.log("******");
return Parse.Promise.as(user);
});
});
};
User Password Input
In order not to change user's password, we can ask user to input his password once we successfully authenticated Google data. We then use the input password to log user in. This is not a good UX, since the purpose of Google Login is to increase usability by letting users not entering password.
Query on Parse.Session
This is a possible solution if you want to use "Revocable Session" feature. In the code above, instead of querying on Parse.User, we can look for any revocable session in Parse.Session class. Then we can call getSessionToken on returned object. This is not optimal solution in cases that we need to know which devices the user is logged in.
Reference:
Parse's Enhanced Session: http://blog.parse.com/announcements/announcing-new-enhanced-sessions/

Categories