Firebase WHERE statement issue - AngularJS - angularjs

In my Firebase I have a entry called 'status' which has some records as 'active' and others as 'inactive'. I am trying to return all records that have the status of 'active'. I am doing the following statement.
new Firebase($rootScope.constants.firebase)
.startAt('active')
.endAt('active')
.once('value', function(snap){
console.log(snap.val());
});
However this is returning NULL.
I am adding data to firebase in the following way:
$firebase(ref).$add({
date: Firebase.ServerValue.TIMESTAMP,
status: 'active'
})
My firebase data looks like the following:
{ "-JSex4_si4a2ZMOLcEuj" : {
"date" : 1406248704619,
"status" : "active",
},
"-JShWyGQzDtAl-F8EkOI" : {
"date" : 1406291928576,
"status" : "active",
}}
Please can someone explain why I am getting NULL and how to get all records with this 'active' status?

Related

Firebase Realtime Database orderByChild data structure - ReactJS

I'm having issues querying data with orderByChild. I would like to query all tasks where provided userID matches any approver id. Task ID is autogenerated so I need to flatten this structure somehow.
Each task has two approvers, and each approver has status, timestamp, id.
Any idea on how to flatten it so I can take advantage of orderByChild?
Tasks:{
"df234dgkjsf234" : {
"approvers" : {
"4U1D23dfsdf23e" : {
"id" : "4U1DWf95rJvgfAwDYs7m",
"status" : "pending",
"timestamp" : "pending"
},
"sdf32fdsf34sdg3" : {
"id" : "FXRkK22TjyxKV6z4UkrU",
"status" : "pending",
"timestamp" : "pending"
}
},
"reason" : "test",
"requester" : "4U1DWf95rJvgfAwDYs7m",
"requesterName" : "Dana Mayers",
"status" : "pending",
"tagetValue" : "QT1IkGHS3mmalyXqdCuD",
"taskName" : "Title Change",
"timestamp" : 1644773238,
"value" : "New Title"
},
"d4S34FSAdsf43FM" : {
...
}
}
I want to make ideally one query to get this data as opposed to querying by Approver1 and then by Approver2
Tasks:{
"df234dgkjsf234" : {
"Approver1" : "4U1DWf95rJvgfAwDYs7m",
"Approver1status" : "pending",
"Approver1timestamp" : "pending"
"Approver2" : "FXRkK22TjyxKV6z4UkrU",
"Approver2status" : "pending",
"Approver2timestamp" : "pending",
"reason" : "test",
"requester" : "4U1DWf95rJvgfAwDYs7m",
"requesterName" : "Dana Mayers",
"status" : "pending",
"tagetValue" : "QT1IkGHS3mmalyXqdCuD",
"taskName" : "Title Change",
"timestamp" : 1644773238,
"value" : "New Title"
},
"d4S34FSAdsf43FM" : {
...
}
}
There is no way to do this with one query, since you're looking for two separate values. The closest you can get is by doing two separate queries on (4Approver1 and Approver2 in) the second data structure, and then merging the results in your application code.
The alternative is to add a secondary data structure, where you map from the user ID back to the tasks they're allowed to approve:
UserTasks: {
"4U1D23dfsdf23e": {
"df234dgkjsf234": true,
"d4S34FSAdsf43FM": true
},
"sdf32fdsf34sdg3": {
"df234dgkjsf234": true
}
}
With such an additional structure you can easily find the tasks for a specific UID, and then load the task details for each.
For more on this, I recommend also reading:
Many to Many relationship in Firebase
Firebase query if child of child contains a value
Firebase Query Double Nested

Retrieving child value of unknown parent Firebase, AngularJS

I have basic project on Firebase, AngularJS.
{
"users" : {
"X3IuXTMi9RgOLMKBoqPJtB1JGGQ2" : {
"profile" : {
"firstName" : "test",
"lastName" : "5",
"username" : "test5"
}
},
"poPg2BfHA1gq3qtXNLbuw4X2Zt23" : {
"profile" : {
"firstName" : "test3",
"lastName" : "asdfg",
"username" : "test3"
}
}
}
}
i want to add users by username basically. when type username on alertprompt(ionic) and click add, it will find target username and get uid on its parent. and it will write data on "users/$targetuid/friendrequests/$senderuid"
my closest search result was that: Retrieve data of child of unknown parent ID - Firebase
but i cant use any .ref codes;
Cannot read property 'ref' of undefined
i just can use FirebaseObjectObservable, what im i doing wrong ? why cant i use
firebase.database().ref
or any like this code based on .ref command?
basically cant do anything here: https://firebase.google.com/docs/database/web/read-and-write
im am sort of new on coding, so if its easy or funny dont laugh much. thanks for reading.
I can see two solutions here:
1) Create a usernameToUserid map: on firebase create a new resource usernameToUserid, ike below:
{
"users" : {
"X3IuXTMi9RgOLMKBoqPJtB1JGGQ2" : {
"profile" : {
"firstName" : "test",
"lastName" : "5",
"username" : "test5"
}
},
"poPg2BfHA1gq3qtXNLbuw4X2Zt23" : {
"profile" : {
"firstName" : "test3",
"lastName" : "asdfg",
"username" : "test3"
}
}
},
"usernameToUserid: {
"test5": "X3IuXTMi9RgOLMKBoqPJtB1JGGQ2",
"test3": "poPg2BfHA1gq3qtXNLbuw4X2Zt23"
}
}
This way you can retrieve the userId and then the user profile with the username.
2) Retrieve all users and search locally for username, terrible idea.

Meteor/MongoDB - How to get single elements from an object array and display them in a table?

I am new to MongoDB and would like to use Meteor Templates to display the queried data in a table.
I have a collection named "infoData" with this structure:
First Document:
{
"_id" : "A-89273498720",
"myItems" : [
{
"itemId" : "item_1",
"username" : "Homer",
"purpose" : "justBecause",
},
{
"itemId" : "item_2",
"username" : "March",
"purpose" : "justBecause2",
},
{
"itemId" : "item_3",
"username" : "Maggie",
"purpose" : "justBecause3",
}
]
}
Second Document:
{
"_id" : "B-564548461117",
"myItems" : [
{
"itemId" : "item_4",
"username" : "Lisa",
"purpose" : "justBecause4",
},
{
"itemId" : "item_5",
"username" : "Lisa",
"purpose" : "justBecause5",
},
{
"itemId" : "item_6",
"username" : "Bart",
"purpose" : "justBecause5",
}
]
}
Now I need to retrieve "itemId" as well as "username" and "purpose" with the "itemId" as a query operator. The "itemId" is unique. My first problem is to get the data. For example I tried this to get the single "itemId" field "item_2":
infoData.findOne({"myItems.itemId": "item_2"}, {_id: 0, 'myItems.$': 1})
which gets the same result as
infoData.findOne(
{
'myItems.itemId': "item_2"
},
{
'_id': 0, 'myItems': {$elemMatch: {'itemId': "item_2"}}
})
I am unsure if this is the result I need, because when I put this query in JSON.stringify() to see the data in the console I see all fields and objects within the array of the doc which contains "item_2" and not only the data "item_2" of the field "itemId". A possibility to get all fields "itemId", "username" and "purpose" of the query (only the object containing item_2) so that I can iterate over it later in a table would also work for me.
The second issue is that I need to display the data in a table.
So I wrote this helper:
'itemInfoDisplay': function() {
if (Meteor.userId()) {
var itemInfos= infoData.findOne(
{"myItems.itemId": "item_2"}, {_id: 0, 'myItems.$': 1});
return itemInfos
}
}
and want to show the data in a table:
{{#each itemInfoDisplay}}
{{#each myItems}}
<tr>
<td><h4>{{ itemId }}</h4></td>
</tr>
{{/each}}
{{/each}}
I know there is something wrong with the code and also with the HTML template. I guess that the result of the mongoDB query is not an array? Is it possible to make it to one? Is the used mongo query the correct solution for my needs?
At the end I just need to get all data which is assigned to a specific "itemId" and display it in a table. I would appreciate anything that helps.
I can think of two ways to do this. The first is to use a projection as mentioned in this post: Retrieve only the queried element in an object array in MongoDB collection
However, it appears you're using that $elemMatch format. If it's not working, not sure if you want to try find() rather than findOne(). There may be a difference in the way Meteor is sending the query to mongodb.
If that doesn't work, the second way is a little bit of a hack but will work. We take advantage of the fact that findOne (unlike find) is synchronous on the client. So we can get the record, then manually do a forEach to only get the appropriate array elements and return that array. Something like this:
var itemInfos= infoData.findOne({"myItems.itemId": "item_2"}, {_id: 0, 'myItems.$': 1});
var items = [];
itemInfos.myItems.forEach(function(myItem) {
if (myItem.itemId == "item_2") {
items.push(myItem);
};
});
return items;
If you use lodash, you can skip the forEach loop and use filter:
return( _.filter(itemInfos.myItems, {itemId: "item_2"}) );
The ideal way would be to restrict the data at the query level, but if that doesn't work option 2 should.

How to find documents in MongoDb matching a field and subdocument field that are in an array

The document structure is as follows:
{
"_id" : "V001-99999999",
"vendor_number" : "V001",
"created_time" : ISODate("2016-04-26T22:15:34Z"),
"updated_time" : ISODate("2016-06-07T21:45:46.413Z"),
"items" : [
{
"sku" : "99999999-1",
"status" : "ACTIVE",
"listing_status" : "LIVE",
"inventory" : 10,
"created_time" : ISODate("2016-05-14T22:15:34Z"),
"updated_time" : ISODate("2016-05-14T20:42:21.753Z"),
},
{
"sku" : "99999999-2",
"status" : "INACTIVE",
"listing_status" : "LIVE",
"inventory" : 10,
"created_time" : ISODate("2016-04-26T22:15:34Z"),
"updated_time" : ISODate("2016-06-06T20:42:21.753Z"),
}
]
}
I want to obtain the sku from the item, the conditions are:
1) "vendor_number" = "XXX"
2) items.status = "ACTIVE" AND items.updated_time < [given_date]
Result example:
"sku" : "99999999-2"
or csv:
"sku","99999999-2"
Thank you for your support.
This should be what you want. Although I'm assuming you wanted "status": "active"?
db.getCollection('collection').aggregate([
{ $match: { "vendor_number": "XXXX" } },
{ $project: {
"items": {
$filter: {
input: "$items",
as: "item",
cond: { $eq: ["$$item.status", "ACTIVE"] } // or maybe ["$$item.listing_status", "LIVE"] ?
}
}
}
},
{ $project: { "items.sku": true } }
])
I love using aggregation to manipulate stuff. It's great all the things you can do with it. So here's what's going on:
The first part is simple. The $match step in the aggregation pipeline says just give me documents where vendor_number is "XXXX".
The next part is a bit hairy. The first projection step creates a new field, called "items", I could have called it "results" or "bob" if I wanted to. The $filter specifies which items should go into this new field. The new "items" field will be an array that will have all the results from the previous items field, hence the input: "$items", where you're using the keyword "item" to represent each input item that comes into the filter. Next, the condition says, for each item, only put it in my new "items" array if the item's status is "ACTIVE". You can change it to ["$$items.listing_status", "LIVE"] if that's what you needed. All of this will pretty much give you you're result.
The last project just get's rid of all other fields except for items.sku in each element in the new "items" array.
Hope this help. Play around with it and see what else you can do with the collection and aggregation. Let me know if you need any more clarification. If you haven't used aggregation before, take a look at the aggregation docs and the list of pipeline operators you can use with aggregation. Pretty handy tool.

How to update a single element in mongodb

$http.put('/api/datas/' + val[$rootScope.id]._id,val[$rootScope.id].values[0].quantity =$scope.ass);
Above mentioned is the code where val[$rootScope.id]._id is the id of the field in mongodb and val[$rootScope.id].values[0].quantity is the quantity which is to be updated and $scope.ass is the updated value.
How can I update quantity value on MongoDB ?
Try with this code for update database value :
db.databaseName.update(
{ _id: value_of_ID},
{
quantity : value_of_quantity;
},
{ upsert: true }
)

Resources