Authenticate user and add them DB simultaneously - javascript

I want to signup new users (through auth) and then add them (with their names and other info) to my user list database in realtime DB. I can't figure out what I'm doing wrong. Authentication works great but the new user is not being added to the DB.
var fname = document.getElementById('fname').value;
var lname = document.getElementById('lname').value;
var email = document.getElementById('email').value;
in the code below, I register them then add their names to the DB and then send a verification email.
function handleRegister() {
var ref = firebase.database().ref();
console.log(email);
console.log(fname);
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;
var uid = firebase.auth().currentUser.uid;
// [START_EXCLUDE]
if (errorCode == 'auth/weak-password') {
alert('The password is too weak.');
firebase.auth().onAuthStateChanged(user => {
if(user) {
var postData = {
Fullname: fname + lname,
email: email,
};
// Write the new post's data simultaneously in the posts list and the user's post list.
var updates = {};
updates['/Users/' + uid ] = postData;
return firebase.database().ref().update(updates);
}
})
} else {
console.log(error);
}
})
Authentication and send email verification works fine but names are not being added to the DB. Also if there is a better approach to achieve auth,add to DB and send email verification, please let me know. Please help.
This is the updated addition
var addusertoDB = function(user){
var uid = firebase.getAuth().uid;
var postData = {
Firstname: fname,
Lastname: lname,
email: email,
}
// Get a key for a new Post.
var newPostKey = firebase.database().ref().child('Users').push().uid
// Write the new post's data simultaneously in the posts list and the user's post list.
var updates = {};
updates['/Users/' + newPostKey] = postData;
// updates['/user-posts/' + '/' + newPostKey] = postData;
return firebase.database().ref().update(updates);
}
and handle register has been updated to
firebase.auth().createUserWithEmailAndPassword(email, password).then(
addusertoDB).catch(handleCreateUserError);
it's finally being added to the DB (without the uid) but firebase.getAuth().uid is not getting the uid. the error I'm getting is "firebase.getAuth is not a function"

You are trying to handle both the errors and the user update in the same function you have passed to catch(). This means that any code inside that function is only run when firebase.auth().createUserWithEmailAndPassword(email, password) fails.
From the firebase documentation:
createUserWithEmailAndPassword
createUserWithEmailAndPassword(email, password) returns
firebase.Promise containing non-null firebase.User
Creates a new user account associated with the specified email address
and password.
On successful creation of the user account, this user will also be
signed in to your application.
This means that on the successful creation of a user you will have access to the new user via a callback passed into then().
You probably want something like this:
var doSomethingWithNewUser = function(user) {
// Manipulate the newly created User however you like here.
// You don't have to sign them in again.
};
var handleCreateUserError = function(error) {
var errorCode = error.code;
var errorMessage = error.message;
// Do whatever you want with the error codes.
};
firebase.auth().createUserWithEmailAndPassword(email, password)
.then(doSomethingWithNewUser)
.catch(handleCreateUserError);

Related

Stripe API - Workaround for case sensitive email

I'm using the Stripe API and this is using the customer email address in the database however we've just had an issue where someone is signing in to the page using a different case to their sign up and it is not showing them as subscribed.
Obviously I'd like to convert the Stripe emails to all be lowercase but I'm not sure how to do this after getting the email. I am converting the user input to be all lowercase but that just means that if the email in Stripe is not lowercase they are not showing as subscribed.
Thanks in advance
$(document).ready(function() {
var productIDFull = "prod_key00000";
var email = '#User.Identity.Name';
var emailLower = email.toLowerCase();
// check if user has made a purchase in stripe for this product
var hasPurchasedFull = false;
$.ajax({
type: "GET",
url: 'https://api.stripe.com/v1/customers?email=' + emailLower,
headers: {
'authorization': 'Bearer sk_live_0000'
},
success: function(data) {
var isSubscribed = false;
// loop through each customer returned
$.each(data.data,
function(i, customer) {
console.log(customer);
var subscriptions = customer.subscriptions;
console.log(subscriptions);
// loop through each sub
$.each(subscriptions.data,
function(j, subscription) {
console.log(subscription);
var subData = subscription.items.data;
// loop through each plan
$.each(subData,
function(k, planData) {
console.log(planData);
if (planData.plan.product == 'prod_Kc3e_0000' && planData.plan.usage_type == 'licensed') {
isSubscribed = true;
}
});
});
I am converting the user input to be all lowercase but that just means
that if the email in Stripe is not lowercase they are not showing as
subscribed.
This sounds expected based on Stripe's documentation: https://stripe.com/docs/api/customers/list?lang=curl#list_customers-email
The email value is case sensitive, so customer Test#example.com will not be returned if you list customers with email test#example.com
I think a better way to handle this is to store a mapping of Stripe customer IDs and email addresses in an internal database and compare against this database instead of a customer list call.

Can Not Store Data From Contact Form To Firebase

I am trying to send the data of my user to firebase using the code given below:
var firestore = firebase.firestore();
var messagesRef = firestore.collection("BookingData");
//listen for submit
document.getElementById('bookingForm').addEventListener('submit',submitForm);
function submitForm(e){
e.preventDefault();
//get values
var email = getInputVal('email');
var packageFields = getInputVal('packageFields');
var name = getInputVal('name');
var phone = getInputVal('phone');
var date = getInputVal('date');
}
// function to get form values
function getInputVal(id) {
return document.getElementById(id).value;
}
//save messages
function saveMessage(email, packageFields, name, phone, date) {
messageRef.add({
email:email,
packageFields:packageFields,
name:name,
phone:phone,
date:date
}).then(function(docRef) {
console.log("Document written with ID: ", docRef.id);
})
.catch(function(error) {
console.error("Error adding document: ", error);
});
}
But nothing is happening.
I am not able to send the data to firebase databse.
it also shows a warning called:
[2020-05-30T03:38:27.083Z] #firebase/app:
Warning: Firebase is already defined in the global scope. Please make sure
Firebase library is only loaded once.
How can I Solve this problem? Please Help/\
Thanks in advance.
Ok, I got The Error I was Not calling The Function. The correct code is:
var firestore = firebase.firestore();
var messagesRef = firestore.collection("BookingData");
//listen for submit
document.getElementById('bookingForm').addEventListener('submit',submitForm);
function submitForm(e){
e.preventDefault();
//get values
var email = getInputVal('email');
var packageFields = getInputVal('packageFields');
var name = getInputVal('name');
var phone = getInputVal('phone');
var date = getInputVal('date');
saveMessage(email, packageFields, name, phone, date);
}
// function to get form values
function getInputVal(id) {
return document.getElementById(id).value;
}
//save messages
function saveMessage(email, packageFields, name, phone, date) {
messageRef.add({
email:email,
packageFields:packageFields,
name:name,
phone:phone,
date:date
}).then(function(docRef) {
console.log("Document written with ID: ", docRef.id);
})
.catch(function(error) {
console.error("Error adding document: ", error);
});
}

Duplication check of Email id and Phone number in Firebase database using JavaScript

I'm completely new to firebase. I'm creating a basic contact form for my application and connected that to the firebase database. I don't have any authentication for my application. . I have set all the rules to True . I want to prevent duplication, if there exists phone number and email in database I want to display an error message.
Below is my code which I have tried
firebase.initializeApp(firebaseConfig);
// Reference messages collection
// Listen for form submit
document.getElementById('contactform1').addEventListener('submit', submitForm);
// Submit form
function submitForm(e) {
e.preventDefault();
// Get values
var fname = getInputVal('fname');
var lname = getInputVal('lname');
var email = getInputVal('email');
var phone = getInputVal('phone');
var skills = getInputVal('skills');
var jobId = getInputVal('jid');
var linkedin = getInputVal('linkedin');
var github = getInputVal('github');
var location = getInputVal('location');
// Save message
saveMessage(fname, lname, email, skills, phone, jobId, linkedin, github, location, );
// file upload
var fileButton = document.getElementById("fileButton");
var file = fileButton.files[0];
firebase.storage().ref('self/' + file.name).put(file);
}
// Function to get get form values
function getInputVal(id) {
return document.getElementById(id).value;
}
// Save message to firebase
function saveMessage(fname, lname, email, skills, phone, jobId, linkedin, github, location) {
firebase.database().ref().child('self/data/' + phone).set({
name: fname + " " + lname,
email: email,
phone: phone,
skills: skills,
jobId: jobId,
linkedin: linkedin,
github: github,
location: location
});
}
//snapshot to check the values in database
firebase.database().ref().child('self/data/' ).on('child_added', snap => {
var name = snap.child('name').val();
var email = snap.child('email').val();
var phone = snap.child('phone').val();
var skills = snap.child('skills').val();
var jobId = snap.child('jobId').val();
var linkedin = snap.child('linkedin').val();
var github = snap.child('github').val();
var location = snap.child('location').val();
$('#table_bdy').append('<tr><td>' + name + '</td><td>' + email + '</td><td>' + phone + '</td><td>' + skills + '</td><td>' + jobId + '</td><td>' + location + '</td><td>' + github + '</td><td>' + linkedin + '</td></tr>')
})
Before saving the new values to the database, retrieve the data from the database and check if the email written in the form is the same as an email retrieved from the database. For example:
var newEmail = getInputVal('email');
firebase.database().ref().child('self/data/' ).on('child_added', snap => {
var name = snap.child('name').val();
var email = snap.child('email').val();
if(newEmail.trim() === email.trim())
{
console.log("email already exists in the database");
}
else
{
saveMessage(fname, lname, newEmail, skills, phone, jobId, linkedin, github, location);
}
});
Try the following:
firebase.initializeApp(firebaseConfig);
// Reference messages collection
// Listen for form submit
document.getElementById('contactform1').addEventListener('submit', submitForm);
// Submit form
function submitForm(e) {
e.preventDefault();
// Get values
var fname = getInputVal('fname');
var lname = getInputVal('lname');
var newEmail = getInputVal('email');
var newPhone = getInputVal('phone');
var newskills = getInputVal('skills');
var newjobId = getInputVal('jid');
var newlinkedin = getInputVal('linkedin');
var newgithub = getInputVal('github');
var newlocation = getInputVal('location');
saveMessage(fname, lname, newEmail, newskills, newPhone, newjobId, newlinkedin, newgithub, newlocation);
}
function saveMessage(fname, lname, newEmail, skills, phone, jobId, linkedin, github, location) {
let ref = firebase.database().ref().child('self/data/');
ref.on('value', snap => {
if(snap.exists())
{
snap.forEach(childSnapshot => {
var name = childSnapshot.child('name').val();
var email = childSnapshot.child('email').val();
var phone = childSnapshot.child('phone').val();
var skills = childSnapshot.child('skills').val();
var jobId = childSnapshot.child('jobId').val();
var linkedin = childSnapshot.child('linkedin').val();
var github = childSnapshot.child('github').val();
var location = childSnapshot.child('location').val();
var status = childSnapshot.child('status').val();
console.log(status);
if (newEmail.trim() === email.trim())
{ //check if email exists
console.log("email already exists in the database");
}
else
{
console.log('hello');
firebase.database().ref().child('self/data/' + phone).set({
name: fname + " " + lname,
email: email,
phone: phone,
skills: skills,
jobId: jobId,
linkedin: linkedin,
github: github,
location: location
});
}
});
}
else
{
firebase.database().ref().child('self/data/' + phone).set({
name: fname + " " + lname,
email: email,
phone: phone,
skills: skills,
jobId: jobId,
linkedin: linkedin,
github: github,
location: location
});
}
});
}
// Function to get get form values
function getInputVal(id) {
return document.getElementById(id).value;
}
First you need to retrieve the values from the form, and then call the method saveMessage in the method check if node self/data exists, then retrieve the data and check if email already exists in the database.

Firebase web app - can't get user.uid when creating new account

I am working on a small web app and I have hit a roadblock that I can't seem to overcome. I am able to register a new account, but I would like to save additional data to a database right after signing up.
This is what I have that I am confident that works fine.
$("#user-sign-up-button").click(function(){
var firstName = $("#new-user-first-name").val();
var secondName = $("#new-user-surname").val();
var charity = $("#new-user-charity-account").val();
var userEmail = $("#new-user-email").val();
var userPassword = $("#new-user-password").val();
var secondPassword = $("#new-user-repeated").val();
firebase.auth().createUserWithEmailAndPassword(userEmail, userPassword)
.catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
// ...
});
});
Now in regards to saving the additional variables to the database I have tried both of the below within .then part of createuserWithEmailAndPassword.
.then(
function(user){
var root = firebase.database().ref();
var uid = user.uid;
alert(uid);
var postData = { firstName: first_name,
secondName: second_name,
email: user_email,
isCharity: charity };
root.child("users").child(uid).set(postData);
}
function writeUserData(first_name, second_name, charity, user_email) {
firebase.database().ref('users/' + user.uid).set({
firstName: first_name,
secondName: second_name,
email: user_email,
isCharity: charity
});
)
Both of the above solutions work within onAuthStateChanged but I want to capture the data at sign up, not every time someone signs in.
Any assistance would be great.
You must use .onAuthStateChanged to get at firebase.auth().currentUser. It's asynchronous and will be empty/null until it resolves. Also, don't forget that new email based accounts will not be .emailValidated:true until they have clicked a verification email link. ...something to consider.

How to use variable between functions

I'm having a problem of using variables between functions. As you can see down below User.username is available and good at the sign up page, but when you go to the login page I told it to first alert the value of User.username, and it alerts undefined? I'm confused here. I'm pretty sure I'm missing a concept here. Anyways Thank you so much!:
Here is a plunkr: http://plnkr.co/edit/qB3Gkeq5ji1YQyy0kpGH
Here is my script.js:
app.controller("AuthCtrl", ["$scope", "Auth","$rootScope",
function($scope, Auth, $rootScope) {
var User = {}
$scope.createUser = function(username, email, password) {
$rootScope.usernames = username
User.username = username
$scope.message = null;
$scope.error = null;
var ref2 = new Firebase("https://uniquecoders.firebaseio.com/");
ref2.createUser({
email: $scope.email,
password: $scope.password
}, function(error, userData) {
if (error) {
switch (error.code) {
case "EMAIL_TAKEN":
alert("The new user account cannot be created because the email is already in use. Try to login");
break;
case "INVALID_EMAIL":
alert("The specified email is not a valid email.");
break;
case "INVALID_PASSWORD":
alert("The Specified Passowrd Is not valid.")
break;
default:
alert("Error creating user:", error);
}
} else {
alert("Successfully created user account with username" + User.username);
window.location.hash = "/User"
}
});
};
$scope.logIn = function(){
alert(User.username)
$rootScope.usernames = User.username
$scope.message = null;
$scope.error = null;
var ref2 = new Firebase("https://uniquecoders.firebaseio.com/");
ref2.authWithPassword({
"email" : $scope.logInemail,
"password" : $scope.logInemailpassword
}, function(error, userData){
if(error){
alert("Login Failed Because : " + error)
}
else{
alert("Logged In!")
window.location.hash = "/User"
}
})
}
/* $scope.removeUser = function() {
$scope.message = null;
$scope.error = null;
Auth.$removeUser({
email: $scope.email,
password: $scope.password
}).then(function() {
$scope.message = "User removed";
}).catch(function(error) {
$scope.error = error;
});
};*/
}
]);
When page reloads the entire javascript is re executed. So user object populated in registration process is no longer available in login function because page has reloaded on clicking on signup button.
So we need to store the user name in cookie so that we can access it any time. Even when its removed from javascript runtime it will be there in the browser cache.
Its risky to store passwords in cookies for security issues.
On successful registration save the username in cookie.
Some thing like this
document.cookie ="username =" +username + "; " +"email ="+ email;
In login function get cookie values and check if email of user is same as entered
function getCookie(name ) {
var pairs = document.cookie.split("; "),
count = pairs.length, parts;
while ( count-- ) {
parts = pairs[count].split("=");
if ( parts[0] === name )
return parts[1];
}
return false;
}
var username=getCookie("username");
var email=getCookie("username");
if($scope.logInemail ==email)
{
alert(username);
}
You have to remember that a web application is a communication between the browser the the web server. The browser and the server can be on different machines (even if they aren't when you are testing.)
There are two ways to make this work
While the browser and the server communicate some information is saved and passed back and forth on both ends -- this is called a cookie. This is the most common way to do save data between pages. The browser requests a page. When it get the reply from the server it contains a cookie. The next time the browser requests a page it includes the cookie in it's request. In this way the server knows the request is related to the prior request.
The server is smart enough to keep track of all "sessions" by different browsers. It then saves session data about that communication -- when it gets the next request from the same browser it goes to the session data and retrieves information about that that browser and what it was doing. (Often this is done with cookies.)

Categories

Resources