Input Value doesn't save, when pushing onto array gives undefined value - javascript

I am trying to update the user account details in firebase but I have noticed that the input value for one of my fields keeps coming up as undefined even when I console.log it. I am working in two files one is a loginjs file in which I am defining the user input.
signUpForm.addEventListener('click', function (e) {
e.preventDefault();
isSigningUp = true;
var email = signUpEmailInput.value;
var password = signUpPasswordInput.value;
var displayNameUser = displayNameInput.value;
var userPrivateKey = signUpPrivateKey.value;
var user = firebase.auth().currentUser;
var photoURL = "https://www.gravatar.com/avatar/" + md5(email);
if (signUpPasswordInput.value !== signUpPasswordConfirmInput.value) {
setSignUpError('Passwords do not match!');
} else if (!displayNameUser) {
setSignUpError("Display Name is required!");
} else if (!userPrivateKey) {
setSignUpError('You need to set a Private Key!');
} else {
auth.createUserWithEmailAndPassword(email, password)
.then(function (user) {
user.updateProfile({
displayName: displayNameUser,
photoURL: photoURL,
privateKey: userPrivateKey
}).then(function () {
// Update successful.
window.location.href = 'chat.html';
}).catch(function (error) {
// An error happened.
window.alert("Some unexpected error happened!");
});
user.sendEmailVerification().then(function () {
// Email sent.
}).catch(function (error) {
// An error happened.
window.alert("Email was not able to send!");
});
})
.catch(function (error) {
// Display error messages
setSignUpError(error.message);
});
}});
The weird thing is that the user input for my displayname and photoURL are working just fine, but when it comes to my private key user input it registers the input when it goes to the chat page and I do a console.log(user.privatekey) It says it is undefined.
In my chatjs file, thats when I am pushing the all the user profile information. The chatjs file basically allows a user to send a message, the message and all the user profile information gets stored onto the firebase database.
messages.push({
displayName: displayName,
userId: userId,
pic: userPic,
text: myString.toString(),
privatekey: user.privatekey,
timestamp: new Date().getTime() // unix timestamp in milliseconds
})
.then(function () {
messageStuff.value = "";
})
.catch(function (error) {
windows.alert("Your message was not sent!");
messageStuff;
});
The thing again is that the privatekey does not get stored at all, which is what I am not understanding, since it is registering user input in the loginjs file but when I go to the chatjs file it keeps saying the value is undefiend. I have googled everywhere and I still haven't found a solution to it. Any help would be greatly appricated!

It's because the Firebase user object you receive from Firebase is not customizable. When you call the createUserWithEmailAndPassword(email, password) method, it returns a specifically defined user object back to you - check out the docs for the properties of this object.
The properties displayName and photoURL both work because they are already properties of the user returned. privateKey is not an existing property of the Firebase user object, and Firebase doesn't know how to handle an update call for a property that isn't defined. Check out this question & answer where Frank explains that Users in Firebase aren't customizable - you need to store any extra info separately.

Related

Wait for firebase.auth initialization before reading another function

I am very new with firebase and javascript.
My project: Build a private messaging app. To do that, I want to define a sub collection in firestore for private messaging using the current user id and the destination user id.
Here is the function that allows this:
// generate the right SubCollection depending on current User and the User he tries to reach
function dmCollection(toUid) {
if (toUid === null) {
// If no destination user is definer, we set it to the below value
toUid = 'fixed_value';
};
const idPair = [firebase.auth().currentUser.uid, toUid].join('_').sort();
return firebase.firestore().collection('dms').doc(idPair).collection('messages');
};
My problem: I want to use the firebase.auth().currentUser.uid attribute, but it looks like the function is not waiting for firebase.auth initialization. How can I fix this problem?
Additional information:
I have two functions that are calling the first one (dmCollection):
// retrieve DMs
function messagesWith(uid) {
return dmCollection(uid).orderBy('sent', 'desc').get();
};
// send a DM
function sendDM(toUid, messageText) {
return dmCollection(toUid).add({
from: firebase.auth().currentUser.uid,
text: messageText,
sent: firebase.firestore.FieldValue.serverTimestamp(),
});
};
If I correctly understand your problem ("it looks like the function is not waiting for firebase.auth initialization"), you have two possible solutions:
Solution 1: Set an observer on the Auth object
As explained in the documentation, you can set an observer on the Auth object with the onAuthStateChanged() method:
By using an observer, you ensure that the Auth object isn't in an
intermediate state—such as initialization—when you get the current
user.
So you would modify your code as follows:
// retrieve DMs
function messagesWith(uid) {
return dmCollection(uid).orderBy('sent', 'desc').get();
};
// send a DM
function sendDM(toUid, messageText) {
return dmCollection(toUid).add({
from: firebase.auth().currentUser.uid,
text: messageText,
sent: firebase.firestore.FieldValue.serverTimestamp(),
});
};
// generate the right SubCollection depending on current User and the User he tries to reach
function dmCollection(toUid) {
if (toUid === null) {
// If no destination user is definer, we set it to the below value
toUid = 'fixed_value';
};
const idPair = [firebase.auth().currentUser.uid, toUid].join('_').sort();
return firebase.firestore().collection('dms').doc(idPair).collection('messages');
};
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
var messageText = '....';
sendDM(user.uid, messageText)
} else {
// No user is signed in.
}
});
Solution 2: Use the currentUser property
You could also "get the currently signed-in user by using the currentUser property" as explained in the same doc. "If a user isn't signed in, currentUser is null".
In this case you would do:
var user = firebase.auth().currentUser;
if (user) {
var messageText = '....';
sendDM(user.uid, messageText);
} else {
// No user is signed in.
// Ask the user to sign in, e.g. redirect to a sign in page
}
Which solution to choose?
It depends how you want to call the function(s) based on the user uid.
If you want to call the function(s) immediately after the user is signed in, use Solution 1.
If you want to call the function(s) at another specific moment (e.g. following a user action), use Solution 2.

Firebase logout user all sessions

I am using Firebase authentication in my iOS app. Is there any way in Firebase when user login my app with Firebase then logout that user all other devices(sessions)? Can I do that with Firebase admin SDK?
When i had this issue i resolved it with cloud functions
Please visit this link for more details https://firebase.google.com/docs/auth/admin/manage-sessions#revoke_refresh_tokens
Do the following;
Set up web server with firebase cloud functions (if none exists)
use the admin sdk(thats the only way this method would work) - [Visit this link] (
(https://firebase.google.com/docs/admin/setup#initialize_the_sdk).
Create an api that receives the uid and revokes current sessions as specified in the first link above
admin.auth().revokeRefreshTokens(uid)
.then(() => {
return admin.auth().getUser(uid);
})
.then((userRecord) => {
return new Date(userRecord.tokensValidAfterTime).getTime() / 1000;
})
.then((timestamp) => {
//return valid response to ios app to continue the user's login process
});
Voila users logged out. I hope this gives insight into resolving the issue
Firebase doesn't provide such feature. You need to manage it yourself.
Here is the Firebase Doc and they haven't mentioned anything related to single user sign in.
Here is what you can do for this-
Take one token in User node (Where you save user's other data) in Firebase database and regenerate it every time you logged in into application, Match this token with already logged in user's token (Which is saved locally) in appDidBecomeActive and appDidFinishLaunching or possibly each time you perform any operation with Firebase or may be in some fixed time interval. If tokens are different logged out the user manually and take user to authenticate screen.
What i have done is:
Created collection in firestore called "activeSessions".User email as an id for object and "activeID" field for holding most recent session id.
in sign in page code:
Generating id for a user session every time user is logging in.
Add this id to localstorage(should be cleaned everytime before adding).
Replace "activeID" by generated id in collection "activeSessions" with current user email.
function addToActiveSession() {
var sesID = gen();
var db = firebase.firestore();
localStorage.setItem('userID', sesID);
db.collection("activeSessions").doc(firebase.auth().currentUser.email).set({
activeID: sesID
}).catch(function (error) {
console.error("Error writing document: ", error);
});
}
function gen() {
var buf = new Uint8Array(1);
window.crypto.getRandomValues(buf);
return buf[0];
}
function signin(){
firebase.auth().signInWithEmailAndPassword(email, password).then(function (user) {
localStorage.clear();
addToActiveSession();
}
}), function (error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
if (errorCode === 'auth/wrong-password') {
alert('wrong pass');
} else {
alert(errorMessage);
}
console.log(error);
};
}
Then i am checking on each page if the id session in local storage is the same as "activeID" in firestore,if not then log out.
function checkSession(){
var db = firebase.firestore();
var docRef = db.collection("activeSessions").doc(firebase.auth().currentUser.email);
docRef.get().then(function (doc) {
alert(doc.data().activeID);
alert(localStorage.getItem('userID'));
if (doc.data().activeID != localStorage.getItem('userID')) {
alert("bie bie");
firebase.auth().signOut().then(() => {
window.location.href = "signin.html";
}).catch((error) => {
// An error happened.
});
window.location.href = "accountone.html";
} else{alert("vse ok");}
}).catch(function (error) {
console.log("Error getting document:", error);
});
}
PS: window has to be refreshed to log inactive session out.

How to remove logged in user in Meteor

I'm developing an app in Meteor and I want to know how I do can delete a user's account who is logged into the system? I mean that you can delete your account (like Tinder or Facebook) and the application ejects you because you're already deleted, and you no longer exist.
With a simple button of "Delete your account" attached.
If you could help me; I'm still a novice I'd really appreciate it, I try to retrieve the id of the current user with Meteor.userId(), and I was creating a method in the following way:
Meteor.methods({
SuprimirPersona: function(id) {
var postId = Meteor.userId();
const userId = this.userId;
const p = Meteor.users.findOne(postId);
if (userId && p === userId) {
Meteor.users.remove({
postId: this._id
},
function(error, result) {
if (error) {
console.log("Error removing user:", error);
} else {
console.log("users removed:" + result);
}
})
}
}
});
And calling the method in the following way but it does not give any results, I do not understand why:
'click #Desactivarr': function() {
var postId = Meteor.userId();
Meteor.call('SuprimirPersona', userId, function(error, result) {
if (error) {
console.log("Somee Error");
}
});
Meteor.logout(function() {
FlowRouter.go('/');
});
},
Hope someone could help me! Regards!
I've just answered this question on Meteor Forums:
https://forums.meteor.com/t/how-to-remove-logged-in-user-in-meteor/42639/3
The issue is you're trying to remove Users by postId, instead of Users.remove({_id: id}). You're removing nothing :)
To remove a user from the user's collection. You need to get the userid of the user you want to remove. This you can get by calling Meteor.userId() on the client to get the userid of the user or this.userId on the server. You need to logout the user and after a successful logout you can pass the userid you got to the meteor.users.remove(userId)
You are doing some unnecessary things on the client and server side - like getting the same user id multiple times, not even passing it to the server side method and then getting it again.
I think what you are trying to do is get the id of a user that posted something and pass it to the server side, where you check if the poster's id is the same as the id of the current user. If so, you remove the user, otherwise nothing happens.
'click #desactivarr' : function() {
var postID = <get the id of the user you want to delete here>;
Meteor.call("suprimirPersona", postID, callbackfunc);
}
Then on the server side it would be
Meteor.methods({
suprimirPersona : function(postID) {
var userID = Meteor.userId();
if (userID && postID === userID) {
Meteor.users.remove({ postId : userID })
}
}
});
Meteor.userId() and this.userId return the id of the currently logged in user that is executing the code on the client side or making the request to a server side method.

how to get current user on firebase

I would like to know how how to get the current user. I am making a function where the user is creating a group and would like to add the user making the group to it at the same time. I can make the group fine, that was simple enough. But I do not know how to get to the user object outside of the simple login object.
I'm sorry if there are several topics stating this already, but I have been looking for hours and have not been able to find anything that explains it. Any help would be appreciated.
The currently logged in user is returned from Simple Login's callback. This callback runs when your user authenticates, or if your user is already authenticated, it runs at the time of page load.
Take this code form the simple login docs:
var myRef = new Firebase("https://<your-firebase>.firebaseio.com");
var authClient = new FirebaseSimpleLogin(myRef, function(error, user) {
if (error) {
// an error occurred while attempting login
console.log(error);
} else if (user) {
// user authenticated with Firebase
console.log("User ID: " + user.uid + ", Provider: " + user.provider);
} else {
// user is logged out
}
});
The user object is exposed in the callback. It's only in scope during the execution of that callback, so if you want to use it outside, store it in a variable for reuse later like this:
var currentUser = {};
var myRef = new Firebase("https://<your-firebase>.firebaseio.com");
var authClient = new FirebaseSimpleLogin(myRef, function(error, user) {
if (error) {
// an error occurred while attempting login
console.log(error);
} else if (user) {
// user authenticated with Firebase
currentUser = user;
} else {
// user is logged out
}
});
...
// Later on in your code (that runs some time after that login callback fires)
console.log("User ID: " + currentUser.uid + ", Provider: " + currentUser.provider);

Geddy Save User

I am currently involved helping out on a project which involves using the Geddy js framework, which it is my first time using. I am currently trying to fix the create method inside a model for users. Here is the code below:
this.create = function (req, resp, params) {
var self = this
, user = geddy.model.User.create(params);
//need to ensure that the user agrees with the terms and conditions.
// Non-blocking uniqueness checks are hard
geddy.model.User.first({username: user.username}, function(err, data) {
if (data) {
params.errors = {
username: 'This username is already in use.'
};
//self.transfer('add');
}
else {
if (user.isValid()) {
user.password = cryptPass(user.password);
user.suburb = "";
user.state = "";
user.postcode = "";
}
user.save(function(err, data) {
if (err) {
params.errors = err;
self.transfer('add');
}
else {
// setup e-mail data with unicode symbols
var mailOptions = {
from: "App ✔ <hello#app.com>", // sender address
to: user.email, // list of receivers
subject: user.username + " Thank you for Signing Up ✔", // Subject line
text: "Please log in and start shopping! ✔", // plaintext body
html: "<b>Please log in and start shopping!✔</b>" // html body
}
smtpTransport.sendMail(mailOptions, function(error, response){
if(error){
console.log(error);
}else{
console.log("Message sent: " + response.message);
}
// if you don't want to use this transport object anymore, uncomment following line
smtpTransport.close(); // shut down the connection pool, no more messages
});
self.redirect({controller: self.name});
}
});
}
});
};
If you look in the code there is apparently a check to see if the so-called user is valid like so: if (user.isValid()) {
user.password = cryptPass(user.password);
user.suburb = "";
user.state = "";
user.postcode = "";
}
The proceeds on to 'save' regardless whether or not the user is valid. I'm thinking why is the code this way? It sounds nonsensical. I asked the original developer who was on the project about it and he said the model was apparently generated when he created the project.
So in bit of a confused state, if anyone can tell me why the save method is outside the if statement in the first place? Is it something the original creators of Geddy intended? or is really nonsensical and I should change it?
Thanks.
Geddy's save() call will error out if the data is invalid (unless force flag is set, which it isn't). It uses the same isValid() call actually. So, looks like what you have here is just someone's way to have a single error handler for all the error cases.
For user.password being set with crypted data only if the data looks valid, I'm guessing this is simply to make 'must be set' type of validation to work. Chances are that even with an empty password, the crypted string would be otherwise counted as set.

Categories