FireBase: How to modify the object in database? - angularjs

I am using AngularFire. Following is the structure of database:
supermarket = {
name : "Food Market",
products : [
{name : "Chocolates"}
{name : "Fruits"}
]
}
I wanna push a vegetable object in products array. How can i do this in firebase?

Stated in Angular Firebase doc for arrays -
As the array is synchronized with server data and being modified concurrently by the client, it is possible to lose track of the fluid array indices and corrupt the data by manipulating the wrong records. Therefore, the placement of items in the list should never be modified directly by using array methods like push() or splice().
Thus you can not use push() or splice().
Firebase gives its own way of adding items to arrays using $add(item) method.
It internally makes sure that the sync is handled in this concurrent environment.
In your case -
If your model which gets sync with firebase server is
supermarket = {
name : "Food Market",
products : [
{name : "Chocolates"}
{name : "Fruits"}
]
}
You get access to this product array array using a firebase ref.
//create a synchronized array
$scope.products = $firebaseArray(ref);
//adding new item to the array
$scope.products.$add({
{name : "vegetables"}
});

Related

Updating Array of Objects in Firebase Realtime Database in React js

I have a problem with updating certain properties of an array of objects in a real-time database in Firebase.
My object looks like the following (see picture).
Now I want to update the IsComing property of the second participant object.
At the moment I use the updateIsComming() function, but this is not very convincing, because I have to rewrite the whole object.
function updateIsComming() {
const db = getDatabase();
update(ref(db, " your_path/EventModel/" + modelkey ), {
Location: "London",
Participants: [
{ Name: "Bella2", IsComming: "true" },
{ Name: "Tom", IsComing: "true" },
],
});
Instead, I just want to reference the specific prop from that array. For example
Participant[1].IsComming = false;
Is there any way I can access a specific array of an object directly.
Arrays as a data structure are not recommended in Firebase Realtime Database. To learn why, I recommend reading Best Practices: Arrays in Firebase.
One of the reasons for this is that you need to read the array to determine the index of the item to update. The pattern is:
Read the array from the database.
Update the necessary item(s) in the array in your application code.
Write the updated array back to the database.
As you already discovered, this is not ideal. As is common on NoSQL databases, consider an alternative data structure that better suits the use-case.
In this case, an alternative data structure to consider is:
Participants: {
"Bella2": true,
"Tom": true
}
In there, we use the name of the participant as the key which means:
Each participant can be present in the object only once, because keys in an object are by definition unique.
You can now update a user's status by their name with: update(db, "your_path/EventModel/" + modelkey + "/Participants/Tom", false).

Value of keys when no unique value is present

I have an infoBox component in React that needs to be used multiple times.
I have an array of objects.
Each value of the object needs to be passed to the infoBox component leading to the creation of an infoBox.
I am achieving this is by iterating over the object array using map(). I am able to get the output, but I was getting logs in console for unique keys.
Since my object does not have any unique value, I tried using Math.random(). Is it the right approach?
What value do I give for keys, when I do not have unique values in my objects?
userDetails = [{name : "Raj", place : "Chennai"}, {name : "Rani", place : "Mumbai"}, {name : "John", place : "Bengaluru"}]
userDetails.map((user){
return (<InfoBox details = user>);
});
Edit :
userDetails is populated dynamically say based on an organization. When the organization changes, the entire array of objects will be replaced by a new one.
Eg:
userDetails = [{name : "Tom", place : "New York"}, {name : "Pip", place : "Colombo"}, {name : "Davis", place : "Dubai"}]
When you don't have the keys of your object, You can use the index of your loop then doesn't show any warning. It's worked.
You can generate the id with indexOf
userDetails.map((user) => <InfoBox details = {user} key = {userDetails.indexOf(user)}/>)

App engine Datastore : How make a query / filter that return entity count with specific array size?

I have an Entity with different properties, one of the propery is Array of Objects , I'm working with Java using Objectify
now I want to make a query with filter to return count of all entities only with specific array size , E.g messages size=2
Example:
Kind: Request
and
propery :
name messeges
{
"values": [
{
"K1": "V1",
"K2": "V2"
},
{
"K3": "V3",
"K4": "V4"
},
{
"K5": "V5",
"K6": "V6"
}
]
}
Something like :
int count = ofy().load().type(Request.class).filter("?? return count , to query with messages size is 2..").count()
Any suggestions plesae?
There is no way to make such query with the datastore.
But you could add a property to your entity, let's call it values_count, to reflect the values array size and make an equality query on that property instead (e.g. values_count=2)
I'd make it a computed property, automatically updated whenever the entity is updated, see Is it possible to have a computed property on Google App Engine using Java?

Referencing arrays that are nested within multiple objects within MongoDB with Express js

So in my MongoDB Collection I have this structure:
"_id" : "Object("-----------")
"name" : "John Doe"
"tool" : {
"hammer" : {
"name" : "hammer 1",
"characteristics" : [
{
"length" : "9 inches"
},
{
"weight" : "4 pounds"
}
]
I know the data may seem a little strange but I can't put the actual data online so I had to input some dummy data. So essentially what I would like to do is be able to update the array that is nested within those objects. So I would like to be able to update the weight or add a new characteristic that I haven't previously entered into it. So for example, add in "metal" : "steel" as a new entry into the array. Currently I'm using a Rest API built in Node.js and Express.js to edit the db. When I was trying to figure out how to dig down this deep I was able to do it with an array at the highest level, however I haven't been able to figure out how to access an array when its embedded like this. So what I was wondering if anybody knew if it was even possible to edit an array this far down? I can post code from controller.js and server.js file if needed but I figured I'd see if it's even possible to do before I start posting it. Any help would be greatly appreciated!
You can use findAndModify to $push it into the array. You have to specify the path precisely though:
db.tools.findAndModify( {
query: { name: "John Doe"},
update: { $push: { tool.hammer.characteristics: {metal: "steel"} }
} );

How to build a associative-array type O(1) field n mongodb schema

I have started on Mongo only recently, and am adapting myself to thinking document instead of a table based approach.
I have a Schema that looks like (Node.js):
var UserInfo = new mongoose.Schema({
id: Number,
name: String,
friends: [{
id: Number,
name: String,
}]
}, {
collection: 'userInfo'
});
The issue is that if I know my User's id and his friend's id too, I will have to iterate through the entire friends[] to find the friend. In other words, the entire operation is not O(1).
If I were storing this in a JS data structure, I will use an associative array for friends, some something like myuser.friends[his_friend_id] will give me a O(1) access to the friend. How do I achieve the same O(1) in Mongo?
I'm not familiar with mongoose, but if there are issues with creating the structure as you think it should be, then there is good reason for that. My current thinking is that the keys in a nosql schema should never be dynamic as it makes searching difficult, if not impossible.
eg with your current schema you would be able to a search for a user in the friends attribute with something like
userInfo.find({ 'friends.id' = userId })
You can also do
userInfo.find({ id: userId, 'friends.id' = friendId })
but I'm not sure that you could return only the individual friend's data from the search anyway.
If you never need to do similar, then it would appear that you must be storing the relationship in both user's documents, duplicating the data. In that case you might want to consider a collection which simply maps friends to friends, or only store the relationships initiated by a user in that user's friends list.
To answer the actual question, I don't think you want to change your schema, but rather go with loading the user and just doing a filter/first/someother type array search on the list of friends to find the match.
The entire operation of retrieving the user document and getting the friend will never be O(1), because lookups in MongoDB aren't O(1). But you can avoid searching the friends array for the friend. Use $ projection:
> db.test.drop()
> db.test.insert({ "_id" : 0, "friends" : [{ "_id" : 1 }, { "_id" : 2 }, { "_id" : 3 }] })
> db.test.find({ "_id" : 0, "friends._id" : 2 }, { "friends.$" : 1 })
{ "_id" : 0, "friends" : [ { "_id" : 2 } ] }
What I was looking for was a sub-document
Finding a sub-document
Each document has an _id. DocumentArrays have a special id method for
looking up a document by its _id.
var doc = parent.children.id(id);

Resources