Need to write to collection in a collection in Firebase - javascript

I need to change my web app (JavaScript) I use to load products to Firebase Firestore to create a collection ('blue_bottle') in a collection ('promotions'). It use to write straight into a collection ('blue_bottle') which was sharp for time being. What do I have to add to make it write to a collection ('promotions') first, then to collection ('blue_bottle')
I can't seem to find very much JavaScript and Firebase reference.
form.addEventListener('submit', (e) => {
e.preventDefault();
db.collection('blue_bottle').add({
Obviously this was the first thing I tried without success:
form.addEventListener('submit', (e) => {
e.preventDefault();
db.collection('promotions').db.collection('blue_bottle').add({
Now it first need to go to a collection ('promotions') please.
Thank you

The Firestore content model is that a document can only exist in a collection, and a subcollection can only exist in a document. There is no way to nest a collection directly under a collection.
To add something under a nested collection under a document, the syntax is:
db.collection('promotions').doc('the parent document').collection('blue_bottle').add({
...
})
Or shorter:
db.collection('promotions/the parent document/blue_bottle').add({
...
})

Related

Firebase - Create subcollection only if the parent doc exists

In Firestore, when you are deleting a doc, you can specify a condition like { exists: true }, in order to avoid deleting the document if it doesn't exist.
In a concurrent scenario, it is possible that we would only like to add a doc to a subcollection if the parent document exists.
For example, imagine the following NoSql structure:
-comment (doc)
/likes (subcollection created when the first like is given)
-like1
-like2
...
Is it possible to do something like
likeRef.create(data, { parent_exists: true });
??
Is the only way to handle this situation with Transactions (reading the parent doc, and throwing an error when .exists() is false)?
I am afraid of this type of situation because if the sub-collection is created at the same time as the container document is deleted, there could be orphan "entities" in the database that may even break the UI if it is not prepared for these extreme cases.
This is not possible as a single operation in Firestore.
The only way to do this is to start a transaction, then get() the parent document inside the transaction, and add the documents to the subcollection if the parent exists.

Using firebase .update within a .where (instead of .doc)

I am new to firebase and am struggling a little bit.
Currently, I am trying to update an array within a user, within a document. However, I cannot match the user to current user using the unique ID, as each users unique ID is their username, and it may have changed since creation.
I figured the best way to match the documents user to the current user would be to use a .where().get() and then use an "update()" to update the array.
Now, this is where I am getting stuck. In the firebase documents, their example of using .update is attached to a .doc
var washingtonRef = db.collection("cities").doc("DC");
//Atomically add a new region to the "regions" array field.
washingtonRef.update({
regions: firebase.firestore.FieldValue.arrayUnion("greater_virginia")
});
However, as I am using a .where, I assume I have to use references and snapshots. But, I am not quite sure how references work in this scenario and, with that, how to update properly.
Here is the code I have after a while of messing round, but no matter my variations i cannot figure it out. (essentially, I want to add a new project (in this case called "new project" to the users array of postedProjects.)
db.collection('users').where('user_id', '==', this.userInfo.user_id)
.get()
.then(function(querySnapshot) {
querySnapshot.forEach(function(doc) {
doc.data().update({
postedProjects: firebase.firestore.FieldValue.arrayUnion("new project")
})
})
})
This gives me an error of ".update() is not a function".
Is anyone able to help me with my solution to show me how references should properly be used in this scenario?
You're almost there. You can't update the data of DocumentSnapshot though, since that is the in-memory representation of the document data. Instead you need to get the DocumentReference and call update on that.
doc.ref.update({
postedProjects: firebase.firestore.FieldValue.arrayUnion("new project")
})
You need a DocumentReference in order to update() a document. Nothing else will work.
In your code, doc is a QueryDocumentSnapshot type object. If you want the DocumentReference object that refers to the document from that snapshot, use its ref property.
doc.ref.update({
postedProjects: firebase.firestore.FieldValue.arrayUnion("new project")
})

deleting specific part of field in firebase (Angular)

I am trying to remove part of an object in firebase. This is what it looks like in the database:
this is within a specific user id inside a 'users' collection.
The way I am currently trying to delete it:
removeUserLikedProperty(property_id: string) {
console.log(property_id)
return fromPromise(this.usersCollection.doc(`${this._auth.currentUserId}/test/${property_id}`).delete());
}
this is within my service. Then I have this in my ts file:
removeUserLikedProperty(property_id: string) {
this._user.removeUserLikedProperty(property_id);
console.log(property_id)
}
and then finally call this on click in my html:
<button class="button button-previous" (click)="removeUserLikedProperty(property?.property_id)">unlike</button>
From everything that I have read, this is my understanding of how to delete a member of a field. By accessing the users collection, getting user id, then going into 'test' and then removing the specific id. Anyone have any further knowledge on this? May syntax may be completely off!
You're mixing documents and fields. Please Read the documentation about data model
Either way, from the image what I understand you're trying to achieve is to delete a field in a nested object.
You need to know two things: how to delete a field in a document and how to access a field in a nested object
The following should work:
removeUserLikedProperty(property_id: string) {
console.log(property_id);
return fromPromise(this.usersCollection.doc(`${this._auth.currentUserId}`).update({
[`test.${property_id}`]: firebase.firestore.FieldValue.delete()
})
);
}

Returning documents in Cloud Firestore

I'm absolutely new to Firestore and for some reason I can't get it right.
I'm trying to retrieve documents from it that I've just manually entered. Using node.js I make a call for a database snapshot like in the documentation:
db.collection('categories').get()
.then((docs) => {
res.json(docs)
})
But instead of an array of docs or something like this, I get this as a response:
_size is right, I have two documents in the collection - but I can't find them anywhere. What am I missing here?
Your docs variable is of type QuerySnapshot. Look at the methods available on that object. If you just want the raw documents out of it, use the docs property on it to get an array of QueryDocumentSnapshot objects. Each of those will have a method called data() on them to get the raw document data.

Backbone fetch and create with different callback method

We use Backbone's fetch to get some record from server and add to the page, use create to create record and add to the page, the add to the page part is done by add method cause create and fetch will trigger it, now I want they have diff way to add to the page, created record I want to insert(prepend) to the page and fetched record append to the page, is there good way to do this?
I'm making the assumption that you're using the add -event to listen for when to add the record to the page.
Both the create and fetch methods take an options -object as a parameter. This obejct gets passed around quite a bit and it will end up as the 3rd parameter in your add -event triggers as well.
Now what you can do to differentiate between the add -events from create and fetch, add some variable to your options -object that you can easily recognize. For example
var onAdd = function(model, collection, options) {
if(options.isFetch) console.log('this model was fetched!');
if(options.isCreate) console.log('this model was created!');
}
model.on('add', onAdd);
model.fetch({isFetch: true});
collection.create({foo: "bar"}, {isCreate: true});
There might be some more eloquent way of achieving this by examining the options Backbone internally sets in create and fetch for differences, but this way you'll know for sure.

Categories

Resources