Get unique id of specific element in Firebase - javascript

I have my Firebase database structured like this:
{
"userProfile" : {
"X0u2SEFfYEeVmdw4TXl58ou2eYy1" : {
"email" : "jane#yahoo.com",
"name" : "Jane"
},
"cliv7hQ4FsWKTtYksPDXcdDafdi2" : {
"email" : "doe#gmail.com",
"name" : "John Doe",
}
}
}
I'm trying to get the unique id of the element that matches query criteria, for example the key of the element with email equal to doe#gmail.com.
I'm doing this by using:
firebase.database().ref('/userProfile').orderByChild('email').equalTo(email).once( 'value', data => {
let user = data.val();
});
This returns me the entire object with that email, but I only want its unique id ("cliv7hQ4FsWKTtYksPDXcdDafdi2" in this case). What's the best way to achieve this?

When you execute a query against the Firebase Database, there will potentially be multiple results. So the snapshot contains a list of those results. Even if there is only a single result, the snapshot will contain a list of one result.
So:
var query = firebase.database().ref('/userProfile').orderByChild('email').equalTo(email);
query.once( 'value', data => {
data.forEach(userSnapshot => {
let user = userSnapshot.val();
let key = userSnapshot.key;
});
});

Related

How to create a mongoose object and simultaneously log the _id

I'm creating subdocuments in my event model under guests that look like below. I would like to console.log the corresponding subdoc Id as each guest id is created.
{
"guests" : [
{ "phone" : 11111,
"_id" : ObjectId("61ef629981f154bead6b0de4")
},
{ "phone" : 4444444444,
"_id" : ObjectId("61fca19f95b626e017732139")
}
]
}
I followed the mongoose docs but the code from the docs (below) only logs the first id even as each subsequent doc is created because of the index 0.
// create a comment
parent.children.push({ name: 'Liesl' });
const subdoc = parent.children[0];
console.log(subdoc) // { _id: '501d86090d371bab2c0341c5', name: 'Liesl' }
subdoc.isNew; // true
I tried removing the index 0 and the console log just produces the ever-growing guests array.
module.exports.addGuest = async (req, res) => {
const event = await Event.findById(req.params.id);
const phone = req.body.guest;
event.guests.push(phone);
const guestId = event.guests[0];
console.log(guestId);
await event.save();
res.redirect(`/events/${event._id}`);
}
How do I adjust my function to log the corresponding subdoc Id as it's created?
try applying mongoose hooks on your subschema.
mongoose pre save hook is triggered every time a document is saved in your collection and you can log the id of your document which is being saved.

Dynamic key name for mongodb Realm

I'm making a digital Christmas Kalendar for a friend. Every day he can claim a Steam game.
So in mongodb in the user account that I made for him there is a key called codes (object). The structure is as follows:
_id: blbalbalba
codes: {
1 : {
title: GTA V,
code: AISHD-SDAH-HAUd,
claimed_at: ,
},
2 : {
title: Fortnite,
code: HHF7-d88a-88fa,
claimed_at: ,
}
}
Just example data. Now in the client app, when button (door) 7 is pressed/opened I want to insert the current date to the key "claimed_at" in the object with key name "7".
I tried some variations of:
const result = await PrivateUserData.updateOne(
{ id: myID },
{ $set: { "codes.`${door_number}`.date_claimed" : date,
}
}
);
But this doesn't work. What did work was: "codes.5.date_claimed". So a static path. In that case the object with name 5 got it's date_claimed key updated.
But how do I use a dynamic path with a variable instead of a number?
Thanks in advance!
If you know the variable value before calling the query i think both of the bellow can work.
var door_number=5;
var date= new Date("...");
const result = await PrivateUserData.updateOne(
{ id: myID },
{ $set : { ["codes."+door_number+".date_claimed"] : date}}
);
var door_number=5;
var date= new Date("...");
const result = await PrivateUserData.updateOne(
{ id: myID },
{ $set : { [`codes.${door_number}.date_claimed`] : date}}
);
If the dynamic behaviour is based on information on the database, send if you can sample data and expected output, so we know what you need.

I want to add data in mongo collection while updating, but instead its getting updated

I want to add data while I am updating, So the use cases is to add the data in same object when I am making a for loop to store the data into the database. But When I am trying to do this then its getting updated instead of adding in into current present object.
const update_records = async (_id, fileName, filter) => {
try {
await connect_to_mongo();
const result = await execute_reports_model.findOneAndUpdate(_id, {upsert: true}, function (err, doc){
if(err || doc === null){
console.error(err);
const e = new Error('ID not found.');
e.status = 404;
throw e;
}
doc.file_name = fileName;
doc.filters.id = filter._id
doc.filters.name = filter.name
doc.filters.origin = filter.origin
doc.save();
})
return result;
} catch (error) {
console.error(error);
throw error;
}
}
In above function i am trying to add data into existing data which is present in the mongo collection.(using mongoose)
{
"_id" : ObjectId("5f16f4e1291796bb531a06df"),
"student)_count" : 5,
"batch_key" : "ddddwe3-6e4a-4654-8f18-c44b152c52c3",
"report_id" : "5f0ffbcdd264d70c1a3b143aa",
"__v" : 0,
"file_name" : "Student Copy Demand file",
"filters" : {
"id" : "5f0ffb96d67d70c1a3b143e7",
"name" : "USER 2 cards filter",
"origin" : "USER"
}
}
Lets say this above is the data available in the collection.
Now i one for loop I am updating the data with id of the same data.
await update_records(_id, fileName, row);
here in above code, row is for loop row which contains filters, and filters needs to be added with filename in the existing record for which that I will find by that _id
example if row contains below data
{
"id" : "2f0f3fb496d670c513iuroinm",
"name" : "Student Daily attendence",
"origin" : "Student"
}
Then that updated record would look like this:
{
"_id" : ObjectId("5f16f4e1291796bb531a06df"),
"student)_count" : 5,
"batch_key" : "ddddwe3-6e4a-4654-8f18-c44b152c52c3",
"report_id" : "5f0ffbcdd264d70c1a3b143aa",
"__v" : 0,
"file_name" : "Student Copy Demand file",
"filters" : {
"id" : "5f0ffb96d67d70c1a3b143e7",
"name" : "USER 2 cards filter",
"origin" : "USER"
},
{
"id" : "2f0f3fb496d670c513iuroinm",
"name" : "Student Daily attendence",
"origin" : "Student"
}
}
Also this is how my model looks like
report_id:{type:String,trim:true},
file_name:{type:String},
filters:[{
status:{type:String}, // this would updated in another function
id:{type:String},
name:{type:String},
origin:{type:String}
}],
batch_key:{type:String,trim:true},
How can I achieve this?
Edited: Made Model filters Array
const result = await execute_reports_model.findByIdAndUpdate(
_id,
{
$set:
{
filters: [filters_data],
}
});
This above code is updating the filed not inserting another one.
All I want to add new, not update the existing.
I see that you are trying to add new filter object to the filters field, but filters field is the object so it's always replaced.
To add new filter in the filters, you must make filters array and then just append it.
Here first of all your model is depicting the wrong meaning. Your filters should be an array.
If you want more than one object to be stored with commas you should have the array data type for the filters.
Make other model for the object that you need to store in the array of filters.
Lets call it filterModel.
Then your main model should look like:
report_id:{type:String,trim:true},
file_name:{type:String},
filters: filterModel[]=[]
batch_key:{type:String,trim:true},
And your filterModel should have the following:
status:{type:String}, // this would updated in another function
id:{type:String},
name:{type:String},
origin:{type:String}
Edited:
Hello, instead of using set operation you should use push operation to add the entry in the array and not replace the existing values.
So please try the below line of codes.
const result = await execute_reports_model.findByIdAndUpdate(
_id,
{
$push:
{
filters: filters_data,
}
});

MongoDB- Return Array of existing fields by compare collection with Array of object

I'm new to Mongo and trying compare a array with a documents of collections and return list of matching records.
Let me explain:First Array
I have a collection (user) with following documents:
> db.user.find().pretty()
{
"_id" : ObjectId("57358220bf3e7d076b6ccdb1"),
"name" : "Sunny",
"phone" : "9417702107",
"email" : "ssdhiman07#gmail.com"
}
{
"_id" : ObjectId("57358242bf3e7d076b6ccdb2"),
"name" : "Pal",
"phone" : "9015719419",
"email" : "ss998#gmail.com"
}
{
"_id" : ObjectId("57358262bf3e7d076b6ccdb3"),
"name" : "viveky",
"phone" : "8826565107",
"email" : "sds998#gmail.com"
}
Second Array: i have a array of objects that is come from Http request below is structure of array.
{
"contacts" : [
{
"name" : "Sunny",
"phone" : "9417702107"
},
{
"name" : "Sukhpal",
"phone" : "9015719419"
},
{
"name" : "anurag",
"phone" : "9988776655"
},
{
"name" : "vivek",
"phone" : "8826565107"
}
]
}
Now I want to know which objects of Second Array are exists in First Array and which doesn't . Comparison should on basis of phone only . And in result i want same Array as Second Array but with one extra field that is
"exists":"true" or "exists":"false" . Something like this.
{
"contacts" : [
{
"name" : "Sunny",
"phone" : "9417702107"
"exists" :"true"
},
{
"name" : "pal",
"phone" : "90177668899"
"exists" :"false"
}
]
}
So for this i had tried something here is code of node.js with mongoos.
exports.matchcontacts = function(req, res, next)
{
var response = {};
var conArray = req.body.contacts;
var contact_list = [];
for(var i=0; i<conArray.length;i++)
{
var name = conArray[i].name;
var phone = conArray[i].phone;
Users.findOne({"phone":conArray[i].phone},function(err,data)
{
if(err)
{
response = {"error" : true,"message" : "Error fetching data"};
}
else if(!data)
{
contact_list.push({name:name,phone:phone,exists:"false"});
}
else
{
contact_list.push({name:name,phone:phone,exists:"true"});
}
});
}
response = {"error":false,"contacts":contact_list};
res.json(response);
};
But always got null {} empty result, and if i tried to get response inside Callback function then it return only single last compared value.
Problem is in first method is that callback function return result very late so result always empty .
and in second method loop override result and it also inefficient to use callback inside loop it will call no of time. So whole story i had explained
Now Please can anybody help me with code or suggest right way to get desired result thanks
HavenĀ“t used mongodb, but the idea I would use is to first iterate your contacts and make a mapping of the phones to the corresponding object and mark them as non existent:
var obj = {};
for(var i=0; i<conArray.length;i++){
obj[conArray[i].phone] = conArray[i];
conArray[i].exists = false;
}
Then search in some way for the users that have those phones in your db, something like
var results = Users.find(records that have phone in Object.keys(obj) array)
Finally, you iterate your existant records and mark the corresponding contact
for(var i=0;i<results.length;i++){
obj[results[i].phone].exists = true;
}

Finding nested array data with elemMatch in MongoDB/Meteor

collection structure as such:
{"_id" : "abc",
"potentialUsers" : [{"userID" : "def"},
{"userID" : "ghi"}]
},
{"_id" : "123",
"potentialUsers" : [{"userID" : "456"},
{"userID" : "789"}]
},
I want to query if user abc has the user def in their potential users array. My current query (client) is
getPendingLiftRequests: function() {
return collection.find({}, {potentialUsers: {$elemMatch: {userID: Meteor.user().services.facebook.id}}});
}
On the server I publish all of that collection to the user, and then just selectively show it based on the view of the client. However, when I try to use an elemMatch on the array, it just shows all of the records, when it should only show 1.
You don't need $elemMatch here. This should work:
var fId = Meteor.user().services.facebook.id;
return collection.find({'potentialUsers.userID': fid});
Have look at the documentation for minimongo in Meteor:
http://docs.meteor.com/#/full/find
You have to use the fields option to get the desired result.
getPendingLiftRequests: function() {
return collection.find({}, { fields: { potentialUsers: {$elemMatch: {userID: Meteor.user().services.facebook.id}}}});
}

Categories

Resources