firebase - pushing an object to an array angularFire2 - firebase

I have a db in which I want to store data like this:
Books:
0:{pushed Object}
1:{pushed object} ...
As if it is an arrays so I can iterate over it and do the stuff I need to do. The problem is that I am storing data as pic related shows:
pic related
It is storing the object with the push_ID firebase assigns to an object but not with the index of an array. This is how I am pushing the object to my database:
let book_data = {
id: bookId,
name: bookData.name,
author: bookData.author,
genre: bookData.genre,
publishDate: bookData.publishDate
};
this.fb.list(`my-lists/${bookList.name}/books/`).push(bookData);
What am I doing wrong?
If needed, I'm coding this for an ionic project.

If you use push() method, Firebase assign it a unique ID without you doing anything else. so if you want a custom key that you defined, you can use set() to save data to a specified reference, also it can be replacing any existing data at that path.
let book_data = {
id: bookId,
name: bookData.name,
author: bookData.author,
genre: bookData.genre,
publishDate: bookData.publishDate
};
let yourkey = 0;
this.fb.list(`my-lists/${bookList.name}/books/${yourkey}`).set(bookData);
When you set new object next time, you have to change the key again and save data

Related

Firebase storage | how to update customMetaData with merge true

When uploading a file.. I have set the following custom meta data
const metadata = {
customMetadata: {
user: userId,
disabled: 'false'
},
};
and upload it like
uploadBytes(ref(this.str, invoicePath), invoiceFile, metadata),
Now some time later I would like to set disabled to true. Doing smth like this
const metadata = {
customMetadata: {
disabled: 'true',
},
};
updateMetadata(ref(this.str, invoicePath), metadata)
will remove the user key in the customMetaData
Is it possible to update it without setting the user key again??
As far as I know the metadata you pass always completely replaces the existing metadata for that object. If you want to retain values from the previous metadata, you will have to perform a read-modify-write sequence.
Update: Interestingly enough the documentation on updating metadata says:
You can update file metadata at any time after the file upload completes by using the updateMetadata() method. Refer to the full list for more information on what properties can be updated. Only the properties specified in the metadata are updated, all others are left unmodified. updateMetadata() returns a Promise containing the complete metadata, or an error if the Promise rejects.

Vue-Firebase: Updating children & writing to child

I started working with Firebase and Vue also with VueFire and i dont understand how to update child nodes at Firebase.
I opened a firebase project and connected to it and i can push data to it.
Firebase
I made a vue component
import db from '../FireBase'
let team = db.ref('Teams');//Reference to Teams at firebase
let miss = db.ref().child('Teams'); //Attempt to get to the children of Teams
export default {
name: "App",
firebase: {
Teams_loc: db.ref('Teams'),
Mission: this.Teams_loc.child('Teams'),
missionKey: db.ref().child('Teams').push("").key,
},
...
I manage to get the Teams from firebase and send data to it:
this.$firebaseRefs.Teams_loc.push({
"test": "tester"
});
Which works but when i try to update the children inside
this.miss.push({
"where": "am i"
})
I get the following error
Cannot read property 'child' of undefined
And when i try to update a child
this.$firebaseRefs.missionKey.update(arr[0]);//arr[0] is an object
I tried looking at quite a few places but nothing seems to do the trick.
Thanks,
When you do the following you are doing an error at the second line.
Teams_loc: db.ref('Teams'),
Mission: this.Teams_loc.child('Teams'),
There is no child of the Teams node that has a key with the value `Teams.
So if you want to update an item, you first have to get its key (e.g. -LEzOBT-mp.....) and do as follows, as explained in the doc:
updateItem: function (item) {
// create a copy of the item
const copy = {...item}
// remove the .key attribute
delete copy['.key']
//possibly update (or add) some values of (to) the item
this.$firebaseRefs.Teams_loc.child(item['.key']).set(copy)
}
Also (if I am not mistaking) doing db.ref() will generate an error because you have to pass a value to ref().
I suggest that you study a bit more the doc and the example: https://github.com/vuejs/vuefire and https://github.com/vuejs/vuefire/blob/master/examples/todo-app/index.html
Update following your comment. Details on how to "know the random generated key"
According to the documentation:
Each record in the bound array will contain a .key property which
specifies the key where the record is stored. So if you have data at
/Teams/-LEzOBT-mp...../, the record for that data will have a .key of
"-LEzOBT-mp.....".
Look at this part of the doc: https://github.com/vuejs/vuefire#array-bindings.
So with this you will get all the keys of the Teams object. You have now to choose the item you want to update.
You could also declare a query in your firebase object, like:
firebase: {
team21483: this.database
.ref('Teams')
.orderByChild('teamCode')
.equalTo('21483')
}
and you would get an array with only one team, the one with TeamCode = 21483.
The best approach, in this latest case, is to manually bind to this Firebase query with the $bindAsArray (or possibly the $bindAsObject) instance methods, using a variable that you pass to equalTo().

Is a variable for a field name allowed during update in Meteor?

I have been trying to update a collection i have.Problem is,i dont know the field name so am relying on some logic to come up with the field name.
For instance
Er.update({ _id: "BCwrQEdiTr9GMmKWW" }, {
$set: {
"x" : y
}
});
where x is the field name.
This is my code
var obj = {};
obj[x] = y;
Er.update({ _id: "BCwrQEdiTr9GMmKWW" }, {$set: {obj}});
I am getting this error
update failed: MongoError: The dotted field 'ersubjects.0.English' in
'obj.ersubjects.0.English' is not valid for storage.
English is a field under ersubjects so i want to update it this way ersubjects.0.English and it works on mongo.
Why is this not working in meteor?.
You can't store documents that have a dot in the key. See this answer for an explanation.
What you can do is use lodash's extremely handy _.set function to create your object with dynamic keys like this:
var obj = {};
var variableKey = 'ersubjects';
_.set(obj, [variableKey, 0, 'English], 'someValue');
Now you can safely store this object to Mongo.

Meteor update array of objects

I'm using Schema with this Meteor project. I've got an array of objects in the Schema, which I create them this way:
'milestones.$.name'
I create some properties like this, and allow for dynamic insert.
Now, I want to grab a milestone by name from milestones array and update some of its properties.
How can I do this?
I'm trying this at the moment, but still no positive result:
Projects.update(
{_id: currentPostId, 'milestones.name':this.name},
{$set: {'milestones.$': {name: this.name, hours: this.hours, complete:true}}}
);

Why use an object when denormalising data?

In the recent blog post on denormalising data, it suggests logging all of a user's comments beneath each user like so:
comments: {
comment1: true,
comment2: true
}
Why is this not a list like so:
comments: [
"comment1",
"comment2",
]
What are the advantages? Is there any difference at all? While I'm at it, how would you go about generating unique references for these comments for a distributed app? I was imagining that with a list I'd just push them onto the end and let the array take care of the index.
Firebase only ever stores objects. The JS client converts arrays into objects using the index as a key. So, for instance if you store the following array using set:
comments: [
"comment1",
"comment2"
]
In Forge (the graphical debugger), it will show up as:
comments:
0: comment1
1: comment2
Given this, storing the ID of the comment directly as a key has the advantage that you can refer to it directly in the security rules, for example, with an expression like:
root.child('comments').hasChild($comment)
In order to generate unique references for these comments, please use push (https://www.firebase.com/docs/managing-lists.html):
var commentsRef = new Firebase("https://<example>.firebaseio.com/comments");
var id = commentsRef.push({content: "Hello world!", author: "Alice"});
console.log(id); // Unique identifier for the comment just added.

Resources