How to check email exists in firebase? - javascript

Hi I'm using firebase and javascript. I need to check for email id existing or not when new user signs up. This code works for user name or id, but shows error having email as record. I don't want to overwrite firebase unique key generation for each record.
var ref = new Firebase("https://kkk.firebaseio.com/");
var users = ref.child("users");
var userId = document.getElementById("email").value;
function checking()
{
checkIfUserExists(userId);
}
function userExistsCallback(userId, exists) {
if (exists) {
alert('user ' + userId + ' exists!');
} else {
alert('user ' + userId + ' does not exist!');
var check = users.push({ email: username});
}
}
function checkIfUserExists(userId) {
users.child(userId).once('value', function(snapshot) {
var exists = (snapshot.val() !== null);
userExistsCallback(userId, exists);
});
}
I'm getting this error when I enter email.
Error: Firebase.child failed: First argument was an invalid path: "anu#gmail.com". Paths must be non-empty strings and can't contain ".", "#", "$", "[", or "]"
I want my data in firebase to looks like this,
users:{
"ksjhfsjkbv67dsjhbcxcscdg":{
"email": "sdfs#gmail.com"
},
"kXdhbrurjw9974jjdsos_asd":{
"email": "anu#gmail.com"
},
...
Can someone help me?

If you're data in firebase has unique keys then it probably looks something like:
{
users:{
"dsjhfsjkbv67dsjhbcxcscdg":{
"email": "blah#whatever.com"
},
"sXdhbrurjw9974jjdsos_asd":{
"email": "anu#gmail.com"
},
...
}
}
the error your getting is because you cannot have illegal characters as the "keys" for your data so:
{
"anu#gmail.com": "email"
}
would not be acceptable hence the error:
Error: Firebase.child failed: First argument was an invalid path: "anu#gmail.com". Paths must be non-empty strings and can't contain ".", "#", "$", "[", or "]"
the "." is not allowed.
One way to check if your value exists if you do not know the unique key is to do something like:
users.once('value', function(snapshot) {
var exists = false;
snapshot.forEach(function(childSnapshot){
if(userId === childSnapshot.val().email){
exists = true;
}
})
userExistsCallback(userId, exists);
});
you can read more about the for each function here:
https://www.firebase.com/docs/web/api/datasnapshot/foreach.html

I don't think you have to check if the email already has an account because firebase can not create another account with the same email.

Related

How to get N index of array from JSON arrays

Hi I have JSON file that have users nickname, password and token. I'm using a find function to find users from their nicknames. I want to get tokens too.
[
{
"user": [
"bombali",
"reYiz_2031",
"GcjSdUMp"
]
},
{
"user": [
"johndoe",
"testpasswd1_s",
"SdNFccRT"
]
}
]
This is my JSON data file.
I'm checking if nicname is taken or not using this code:
function isUsernameTaken(username) {
const user_Database = require(`${config.path_users}`);
const finded_Name = user_Database.find(
({ user }) => user[0] === username.toLowerCase()
);
if (finded_Name === undefined) {
console.log("This username is usable");
} else {
console.log("This username is unusable");
}
}
Now I want to get token from json by using username and password to use filter. I don't want to use token:SdNFccRT in array. Is it possible? Thanks for all replies.
Using .filter() isn't the best choice in this case. With .find(), the search will stop once one element has been found, but .filter() will keep on going when it doesn't have to.
Given the username and password, you can find the token with a single .find() statement that compares each user object's username and password, then returns the token of the match. You can also use optional chaining to return undefined if no match is found. Like this:
const getToken = (data, uname, pass) => data.find(({user}) => user[0] === uname && user[1] === pass)?.user[2];
const data = [{
"user": [
"bombali",
"reYiz_2031",
"GcjSdUMp"
]
},
{
"user": [
"johndoe",
"testpasswd1_s",
"SdNFccRT"
]
}
];
console.log(getToken(data, 'bombali', 'reYiz_2031'));
console.log(getToken(data, 'none', 'none'));

Mongoose: updating new values only if not null

I already got another solution but cannot understand why mine doesn't work.
I tried to use $set: here but it didn't help. objForUpdate do return "name, lastname" when i print. If i replace {objForUpdate} with {name, lastname} - update works. But I cannot pass the parameters in variable.
//Route to UPDATE user
async updateUser(req, res) {
let { _id, type, name, lastname } = req.body;
try {
let objForUpdate = "";
for (var key in req.body) {
if (req.body.hasOwnProperty(key) && req.body.key !== null && req.body[key] !== "" && key !== '_id') {
console.log("this is key: " + key + ", and this is value req.body[key]: " + req.body[key]);
objForUpdate += key + ", ";
}
}
objForUpdate = objForUpdate.slice(0, -2);
const updated = await Users.updateOne({ _id }, {objForUpdate});
res.send({ updated });
} catch (error) {
res.send({ error });
}
}
If you would debug the code, you'll get it.
Lets say the req.body looks like { name: "foo", lastname: "bar" type: "2", _id: 1} and by the end of the for-loop and the slice op the objForUpdate would be "name, lastname, type" which is a string.
Now when you pass this string to the updateOne op, this part {objForUpdate} will get converted to { objForUpdate: "name, lastname, type" } (a conversion of identifier as key and its defined value as the value of that key).
And that update object is incorrect even with $set operator.
If i replace {objForUpdate} with {name, lastname} - update works. Why?
Because in this case with Object destructuring you unpacked the object as independent variables (name, lastname ...) with values. In this case the {objForUpdate} when passed would become {"name":"foo", "lastname":"bar", "type":"2"} which is correct as update object.

Why isn't my collection.upsert() query NOT setting multiple parameters to the collection?

I have an collection.upsert() function in my Meteor method. For some strange reason it only seems to upsert the first parameter, and ignores to upsert the rest of the parameters. Can someone kindly explain why this is happening?
Find below the events template, where the userId, password, email, names, parameters are passed onto the Meteor method regenerateApiKey in subject
/client/main.js
Template.apiKey.events({
'click .regenerate-api-key': function( ){
var userId = Meteor.userId();
var password = Meteor.user().services.google.accessToken;
var email = Meteor.user().services.google.email;
var names = Meteor.user().services.google.name;
alert("Password: " +password);
alert("email: " +email);
alert("email: " +names);
confirmRegeneration = confirm( "Are you sure? This will invalidate your current key!" );
if ( confirmRegeneration ) {
Meteor.call( "regenerateApiKey", userId, password, email, names, function( error, response ) {
if ( error ) {
alert( error.reason, "danger" );
} else {
+response );
alert( "All done! You have a new API key: " +response );
console.log("Response is: " +response);
}
});
}
}
});
The events template above renders 5 popup Alerts:
POPUP.1 Password: ya29.Glz
POPUP.2 email: centos.east#gmail.com
POPUP.3 email: Centos East
POPUP.4 Are you sure? This will invalidate your current key!
To which I press YES
POPUP.5 All done! You have a new API key: [object Object]
The code below illustrates the Meteor.call( "regenerateApiKey") along with the userId, password, email, names parameters.
/server/main.js
Meteor.methods({
regenerateApiKey: function( userId, password, email, names ){
check( userId, Meteor.userId() );
var newKey = Random.hexString( 32 );
var password = password;
var email = email;
var names = names;
console.log("password: " +password);
console.log("email: " +email);
console.log("names: " +names );
console.log("newKey: " +newKey);
try {
var keyId = APIKeys.upsert( { "owner": userId }, {
$set: {
"key": newKey,
"password": password,
"email": email,
"names": names
}
});
return keyId;
} catch(exception) {
console.log("FAILED UPDATE")
return exception;
}
}
});
In the terminal, I am able to see what is rendered by the code above:
password: ya29.Glz
email: centos.east#gmail.com
names: Cent East
newKey : 337829bb18082690a32f94a3c23b3782
When I query APIKeys.find().fetch() in the console, I get:
key: "337829bb18082690a32f94a3c23b3782"
_id:"PgBmn6zSYiXTbx6tu"
Which indicates that ONLY the newKey variable was set to key BUT the query ignored to set password, email, and names variables.
Can someone kindly explain why the password, email, and names variables aren't being set (included) in the collection?
The reason why only the key was being upsert in the query below:
APIKeys.upsert( { "owner": userId }, {
$set: {
"key": newKey,
"password": password,
"email": email,
"names": names
}
});
was actually false. The ENTIRE query was correctly being carried out.
The fault was in the Publish configuration itself!
The publish configuration ONLY allowed for the key fields value to be displayed!
Find below my Publish configuration code:
Meteor.publish( 'APIKey', function(){
var user = this.userId;
var data = APIKeys.find( { "owner": user }, {fields:
{
"key": true,
} });
if ( data ) {
return data;
}
return this.ready();
});
To correct this issue, I have had to re-configure my publish to the below code:
Meteor.publish( 'APIKey', function(){
var user = this.userId;
var data = APIKeys.find( { "owner": user }, {fields:
{
"key": true,
"password": true,
"email": true,
"names": true
} });
if ( data ) {
return data;
}
return this.ready();
});
I'd like to thank #Ivo in the thread for pointing me in the right direction in regards to this issue.

How to get object field in Parse

Here is my query for a particular User:
var query = new Parse.Query("User");
query.get(userId, {
success: function(user) {
if (user === undefined){
response.success("No such user with this ID: " + userId)
}else{
response.success("successfull " + user.get('authData')); // authData is undefined whereas name, minAge and other primitive types are working fine
}
},
error: function() {
response.error("user lookup failed");
}
});
That user.get('authData') is returning undefined, however other primitive type fields such as name and age are working fine.
I am thinking it is because authData is object
How can I access it?

How to sort Mongoose results depending on whether it's a $regex or $ text in Node.JS?

I have a REST API Call like /item/search which has some query parameters attached to it.
The user can search for entire term or just 3 or more characters of a term.
The Node.JS exports function is as follows,
exports.getSearchedItems = function(req,res){
var searchText = req.query.q;
var searchedString = searchText.replace(/ /g,"|");
var nameRegex = new RegExp('\\b' + searchedString + '.*', 'i');
Item.find()
.or([
{$text: {$search: searchText } },
{'name': {$regex: nameRegex } },
{'score':{'$meta': 'textScore'}
]
)
.sort({'score':{'$meta': 'textScore'}}
.exec(function(err, items){
if(err) console.log('Error Finding Query ' +err);
res.send(items);
});
};
A query Like item/search?q=new+2,
We get the below Error,
Can't canonicalize query: BadValue must have $meta projection for all $meta sort keys
Is there any way I can do a partial OR full search yet maintain the textScore and sort my resulting mongoose documents as per that score.
Cheers and Thanks in Advance.
MongoDB's find() method can take a second optional argument indicating which fields to return and in your case of $text search, the special projection field $meta allows you to get back the score of the matched document so that you can sort on it.
Try modifying your find() query to include the query and the $meta projection as the find() arguments instead of the or() method:
Item.find(
{
"$or":[ {"$text": {"$search": searchText } }, {"name": {"$regex": nameRegex } } ]
},
{
"score" : { "$meta" : "textScore"}
})
.sort({"score": { "$meta": "textScore"} })
.exec(function(err, items){
if(err) console.log("Error Finding Query " + err);
res.send(items);
});

Categories

Resources