Retrieving child value of unknown parent Firebase, AngularJS - 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.

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

Updating a collection inside array of collections in MongoDB

I have a mongo collection workspaces in my MongoDB which consist of records that looks like as follows:
{
"_id" : ObjectId("58bdc4a13504f5ed743ad025"),
"name" : "My workspace",
"user_id" : ObjectId("58b6cf53988a874af070fd3b"),
"uploads" : [
{
"original" : "DE-20__450_GG_5002_N23_994__0136.tif"
},
{
"original" : "DE-20__450_GG_5002_N23_994__0134.png"
},
{
"original" : "DE-20__450_GG_5002_N23_994__0136.png"
},
{
"original" : "DE-20__450_GG_5002_N23_994__0134.tif"
}
]
}
Now my objective is that i want to append something in one of record of array uploads with the match criteria of original field value. For example i want to append "pseg" : "DE-20__450_GG_5002_N23_994__0136.pseg.tif" to the {"original" : "DE-20__450_GG_5002_N23_994__0136.tif"} collection in following way:
{
"_id" : ObjectId("58bdc4a13504f5ed743ad025"),
"name" : "Objective",
"user_id" : ObjectId("58b6cf53988a874af070fd3b"),
"uploads" : [
{
"original" : "DE-20__450_GG_5002_N23_994__0136.tif",
"pseg" : "DE-20__450_GG_5002_N23_994__0136.pseg.tif"
},
{
"original" : "DE-20__450_GG_5002_N23_994__0134.png"
},
{
"original" : "DE-20__450_GG_5002_N23_994__0136.png"
},
{
"original" : "DE-20__450_GG_5002_N23_994__0134.tif"
}
]
}
i tried using $elemMatch and then i added $addToSet in following way:
db.getCollection('workspaces').update({"_id": ObjectId("58bdc4a13504f5ed743ad025"),"uploads": {$elemMatch: {"original": "DE-20__450_GG_5002_N23_994__0136.tif"}}},{$addToSet:{"uploads.$": {"pseg" : "DE-20__450_GG_5002_N23_994__0136.pseg.tif"}}})
but it gives me following error:
Cannot apply $addToSet to a non-array field. Field named '0' has a non-array type object in the document _id: ObjectId('58bdc4a13504f5ed743ad025')
I think i crafted the query wrong can anyone tell me what is wrong and how can i solve it?
Sorry for my bad english :) hope you understood what i said.
Here is the correct syntax. You have to use $set with postional operator to reach the element.
db.getCollection('workspaces').update(
{"_id": ObjectId("58bdc4a13504f5ed743ad025"),"uploads": {$elemMatch: {"original": "DE-20__450_GG_5002_N23_994__0136.tif"}}},
{$set:{"uploads.$.pseg" : "DE-20__450_GG_5002_N23_994__0136.pseg.tif"}})
More information here https://docs.mongodb.com/manual/reference/operator/update/positional/#update-documents-in-an-array
You can simplify your query criteria. You don't need to use $elemMatch operator for single query condition. You can use dot notation.
db.getCollection('workspaces').update(
{"_id": ObjectId("58bdc4a13504f5ed743ad025"),"uploads.original": "DE-20__450_GG_5002_N23_994__0136.tif"},
{$set:{"uploads.$.pseg" : "DE-20__450_GG_5002_N23_994__0136.pseg.tif"}})
More information here
https://docs.mongodb.com/manual/reference/operator/query/elemMatch/#single-query-condition

How get time on timecurrent on node of Firebase using Angular?

I want to show only the time on the view, when use $firebaseArray I get the list of items and i want to get only the time.
Firebase tree
{
"eventmodel" : {
"-KX6kDkufxLg-fLocsN7" : {
"info" : "ok",
"limit" : 2,
"timeCurrentStart" : "29/11/2016 17:38",
},
"-KXBB-R7xAPl65xhlTpg" : {
"info" : "ok",
"limit" : 2,
"timeCurrentStart" : "29/11/2016 17:38",
}
}
}
The Firebase client always retrieves complete nodes. There is no way to get only the timeCurrentStart property of each node.
So either you'll have to store the timeCurrentStart properties in a separate node:
{
"eventmodeltimes" : {
"-KX6kDkufxLg-fLocsN7" : "29/11/2016 17:38",
"-KXBB-R7xAPl65xhlTpg" : "29/11/2016 17:38"
}
}
Or you'll have to retrieve the entire nodes and only show timeCurrentStart:
<span>{{event.timeCurrentStart}}</span>

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.

Using dot notation in Angular on JSON object not working as expected

I am being passed a JSON object via an API service. I have NO CONTROL over the format of the JSON. It is however a valid JSON object:
{
"Template" : {
"Parameters" : {
"Name" : "Test",
"Version" : "1.0"
},
"Fields" : {
"Field" : [{
"Prompt" : "Last Name:"
}, {
"Prompt" : "First Name:"
}, {
"Prompt" : "Middle Name"
}, {
"Prompt" : "ID Number:"
}
]
},
"Captures" : {
"Capture" : [{
"Prompt" : "Picture"
}, {
"Prompt" : "Picture from file"
}, {
"Prompt" : "Signature"
}
]
}
}
}
What I need to do is loop through a list of the Fields in the object, so that I can display values from there. In the case of this example, I am trying to print a list of Prompt values from the Fields.
http://jsfiddle.net/toddhd/0wbfpxkj/9/
<div ng-repeat="item in template.Fields.Field">
{{item.Prompt}}
</div>
This is explained MUCH better by looking at the JSFiddle above.
What I WANT to do is simply get the list of fields using dot/point notation, such as:
template.Fields.Field
But that isn't working for me. In the example, I also made a series of ng-repeats which loop through each collection one by one. That works and produces the desired result, but it's verbose and ugly.
I'm sure I'm just misunderstanding the structure of the JSON object itself, or maybe the correct dot/point notation to get there. But I just can't seem to figure it out. Can you please take a look and tell me where I'm going wrong?
Thank you
It's just missing another Template. It should be template.Template.Fields.Field.
Your html should look like this:
<div ng-repeat="item in template.Template.Fields.Field">{{item.Prompt}}</div>

Resources