I'm saving the user object in localstorage upon creation (to be sure i can use it later inside a custom function, outside the authStateChanged):
const promise = auth.createUserWithEmailAndPassword(email, pass);
promise.then(e => {
var user = firebase.auth().currentUser;
localStorage.setItem('fireUser', JSON.stringify(user));
user.sendEmailVerification();
}).catch(function(error) {
var errorCode = error.code;
var errorMessage = error.message;
});
then i'm retrieving it inside my custom function below, it works when used like user.uid but it gives error "user.delete is not a function" when used as user.delete(), why is that? the variable user looks like this in the localStorage:
my custom function:
var myTimer;
function validTimer(timerValid){
var user = JSON.parse(localStorage.getItem('fireUser'));
// var buser = firebase.auth().currentUser; <-- doesn't work here
myTimer = setInterval(function() {
timerValid++;
localStorage.setItem('fireTimer', timerValid);
if (timerValid == 22) {
// delete in database
var userId = user.uid;
var ref = firebase.database().ref().child('users');
ref.child(userId).once("value", function(snapshot){
if (snapshot.exists()){
database.ref("users/"+userId).remove();
}
});
// delete account
user.delete().then(function() { // this says user.delete is not a function
}).catch(function(error) {
});
}
}, 1000);
}
It’s stripped of its instance methods when you stringify and parse it back. The delete method is an instance method for a firebase user object. In this case your user, although it looks the same, is not a firebase user. It’s just a bare object.
Edit
For persisting the firebase user via the Client SDK, you want to use the firebase.auth().onAuthStateChanged() method. Shortly after your page reloads, this method will fire. Set it here. Straight from the web starting guide:
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.
// ...
}
});
Related
This is the structure of my database, every user is in a child with value as that of their user-id
This is the code i am using
var userId = firebase.auth().currentUser.uid;
return firebase.database().ref('/users/' + userId).child("userName").once('value').then(function(snapshot) {
var username = (snapshot.val() && snapshot.val().username) || 'Anonymous';
$("#name-tag").append(username);
});
I want the userName value and have to display it
First change the way you authenticate the user then create a proper reference to the database.
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
var userDBRef = firebase.database().ref().child("User Database").child(user.uid);
userDBRef.on("value", function(userDB){
$("#para-id").append(userDB.child("userName").val());
});
} else {
// No user is signed in.
console.log("no user!!!");
}
});
Try this code :
var userId = firebase.auth().currentUser.uid;
return firebase.database().ref('/users/' +
userId).child("userName").once('value').then(function(snapshot) {
var username = snapshot.val() ? snapshot.val().username) : 'Anonymous';
$("#name-tag").append(username);
});
If snapshot.val() return null then usename will be 'Anonymus'
I am having trouble removing data from my database on Firebase. I am able to remove data but when I remove the data its removing all my users? I only wanted it to remove the user represented in the user ID.
My JS
function removeUser(userID){
var userRef = firebase.database().ref('users/');
// Returned no user found
//var userRef = firebase.database().ref('users/').child('userID');
// Returned reference child error
//var userRef = firebase.database().ref('users/').child(userID);
userRef.once('value', function(snapshot) {
if (snapshot.val() === null) {
alert("no user found");
}else{
userRef.ref.remove();
}
});
console.log('Remove Success');
}
document.getElementById('removeUserBtn').addEventListener('click', function(){
removeUser(userID);
});
You need to specify the full path to the child you are trying to remove:
var childUserRef = firebase.database().ref(`users/${userId}`)
and call the .remove() method as in : childUserRef.remove()
More details:
https://firebase.google.com/docs/reference/js/firebase.database.Reference
I have a Firebase web app serving as a registration system. When a user registers for a course, the course data is added to their list of all registrations as part of the callback function. When the user registers, the newest class is duplicated in the list. On a page load, each course is only listed once.
Realtime Database Structure
{
courses: {
courseIdA: {
// course data
},
couseIdB ... {}
},
users: {
uid: {
regs: {
courseIdA: true
}
}
}
}
When a user registers, they are added to both the course ID as a member object and to their users object under their uid. The callback fires twice because I'm writing to the courses ref and the users ref. Is there a way to write to both simultaneously? Or do I need to come up with a better structure for the database?
Get classes, listen for changes
PDReg.prototype.getAllClasses = function() {
this.database = firebase.database()
var uid = firebase.auth().currentUser.uid;
var courses = [];
var today = new Date().toISOString();
this.classesRef = this.database.ref('courses');
this.userRef = this.database.ref('users/' + uid + "/regs");
var setClass = function(snapshot) {
var course = snapshot.val();
course.key = snapshot.key;
// check for the current user in a course
if(course.members) {
if(course.members.hasOwnProperty(uid)) {
// This callback fires twice when someone registers
this.buildUserClasses(course);
} else {
this.buildAllClasses(course)
}
} else {
this.buildAllClasses(course)
}
}.bind(this);
// listen for changes to the classes database, rebuild the UI
this.classesRef.orderByChild('start').startAt(today).on('child_added', setClass);
this.classesRef.on('child_changed', setClass);
};
Register
PDReg.prototype.register = function(e) {
// It's a form submit, don't reload the page
e.preventDefault();
var form = this.courseForm;
var classes = [];
var uid = firebase.auth().currentUser.uid;
for (var i=0; i<form.elements.length; i++) {
// build the object to submit and add to an array
}
for (var i=0; i<classes.length; i++) {
this.coursesRef = this.database.ref('courses/' + classes[i].id + '/members/' + uid);
// Write the member object to `courses` under the correct key
this.coursesRef.set({'code': classes[i]['code']}).then(function(classes) {
// write to the user ref
firebase.database().ref('users/' + uid + '/regs/' + id).set(true);
onSuccess(title);
document.getElementById('allCourses').removeChild(document.getElementById(id))
}, function(e) {
onFailure(e, title);
});
}
};
So i'm new to using Firebase and I have been looking at the Firebase documentation but I haven't found how to do the following:
The user puts the following inputs: username, email, password, confirm password.
When I call the "createUserWithEmailAndPassword", if it works, I want at the same time to create entries in the DB in Firebase. I tried writing the following line:
firebase.auth().createUserWithEmailAndPassword(userEmailCreate, userPasswordCreate).then(function(){
//do what I want
}).catch(function (error) {})
But it doesn't work. What am I doing wrong?
Or do you have any suggestions as to how to add additional elements in the entry User using the uid that is created by the authentication method?
function createUser() {
//instance of database Firebase
var database = firebase.database();
//Get inputs from user
var userUsername = document.getElementById("usernameCreation_Field").value;
var userEmailCreate = document.getElementById("emailCreation_field").value;
var userPasswordCreate = document.getElementById("passwordCreation_field").value;
var userPassword2Create = document.getElementById("passwordCreation2_field").value;
if (userPasswordCreate == userPassword2Create && userUsername.length > 0) {
//If passwords match try to create user
firebase.auth().createUserWithEmailAndPassword(userEmailCreate, userPasswordCreate).catch(function (error) {
// Handle Errors here when creating account
var errorCode = error.code;
var errorMessage = error.message;
document.getElementById('createSuccess').style.display = 'block';
document.getElementById('createSuccess').innerHTML = errorMessage;
});
//Passwords don't match
} else if(userUsername.length == 0){
document.getElementById('createSuccess').innerHTML = 'Username must be filled!';
document.getElementById('createSuccess').style.display = 'block';
} else {
document.getElementById('createSuccess').style.display = 'block';
document.getElementById('createSuccess').innerHTML = 'Passwords don\'t match!';
}
}
//Add new user to database
function setUserData(userId, username, email){
firebase.database().ref('users/' + userId).set({
username: name,
email: email,
profile_picture : imageUrl,
topScore : topScore
});
}
Thank you in advance for your time!
Your code is not calling setUserData anywhere, so that would definitely explain why nothing is written to the database.
You're probably looking to call if from the then of createUser...:
firebase.auth().createUserWithEmailAndPassword(userEmailCreate, userPasswordCreate).then(function(userCredential) {
setUserdata(userCredential.user.uid, userUsername, userEmailCreate);
}).catch(function (error) {
// Handle Errors here when creating account
var errorCode = error.code;
var errorMessage = error.message;
document.getElementById('createSuccess').style.display = 'block';
document.getElementById('createSuccess').innerHTML = errorMessage;
});
Here is the code that I am using to get the details of the user when they log in using google, facebook or twitter.
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 uid = user.uid;
var phoneNumber = user.phoneNumber;
var providerData = user.providerData;
user.getToken().then(function(accessToken) {
console.debug('user', user);
document.getElementById('name').textContent = displayName;
document.getElementById("avatar").src = photoURL;
});
} else {
console.log('not logged in');
}
});
Then in the html by writing <p id="name"></p> the entire name of the user is displayed.
How do I display just the first name of the user?
You can do it like this;
document.getElementById('name').textContent = (displayName.split(' '))[0];
First and last name are available from most social providers just after you log in, but you will need to save them to your database as Firebase does not. What each provider calls first and last name varies, though.
Documentation at https://firebase.google.com/docs/reference/js/firebase.auth.Auth#signinwithpopup
firebase.auth
.signInWithPopup(new firebase.auth.GoogleAuthProvider())
.then((user) => {
const firstName = user.additionalUserInfo.profile.given_name;
const lastName = user.additionalUserInfo.profile.family_name;
});
firebase.auth
.signInWithPopup(new firebase.auth.OAuthProvider('microsoft.com'))
.then((user) => {
const firstName = user.additionalUserInfo.profile.givenName;
const lastName = user.additionalUserInfo.profile.surname;
});