Firestore - Query, then update - javascript

I want to return an item with a specific ID and perform an update operation on it. My query gets the right result, but it won't let me update it.
I tried following this tutorial: https://www.youtube.com/watch?v=mYyPbfpoZeM
And read the documentation. Both didn't help. Other threads to the same topic are, well, different.
I have a database of objects which have a unique ID stored as integer.
I have an HTML form to get an ID as user input and the query below to retrieve the according object.
I tried this. The query worked, the update didn't.
db.collection('objects').where('ID','==', ID ).get().then((snapshot) => {
snapshot.docs.forEach( doc => {
console.log('debug');
console.log(doc.data().ID);
})
});
I am still new to firebase and js, so please forgive me if my code is uterly wrong.
I am currently stuck with this:
db.collection('objects').where('ID','==', ID ).get().then((doc) => {
console.table(doc);
});
Which is still not working.
For the second snippet an I currently get an unlegible table in which I can't really find the object I was looking for.
How do I update a single value in a single document?
EDIT: I forgot my implementation attempts of the update function.
I tried doc.update({value:0}) inside the for loop in snippet one which yielded doc.update is not a function. Similarly for doc.data().update(...).
In the second snippet I mainly tried to see what I got returned and ran variations of the above mentioned uodate function. With no success.

I managed to get it to work by studying the part of the firestore documentation that goes more into detail about the actual functions. Somehow it was hard for me to find this.
db.collection("users").where("name", "==", somename).limit(1).get().then(query => {
console.log(query);
const thing = query.docs[0];
console.log(thing.data());
let tmp = thing.data();
tmp.current_game_play = tmp.current_game_play + 1;
console.log(tmp);
thing.ref.update(tmp);
});
So I use where to get a Query object, use get to get a a querySnapshot inside the then promise resolve, use docs[0] to retrieve the first (and only) documentSnapshot and finally ref to get a reference that makes the whole thing updatable later.

try this:
var objectRef= db.collection("objects").doc(ID);
objectRef.update({
value: 0
}).then(function() {
console.log("Document successfully updated!");
}).catch(function(error) {
// The document probably doesn't exist.
console.error("Error updating document: ", error);
});

Related

Query documents in firestore from an array of ID's

I was wondering how I can query documents from a firestore collection from an array of ID's? I only want the documents in the collection that are in the array of ID's. I looked at another answer and think my approach is correct, however, I am getting an error.
(node:15105) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'data' of undefined
> at /Users/username/SideProjects/projectname/functions/index.js:40:38
> at processTicksAndRejections (internal/process/task_queues.js:95:5)
The error happens because the function is not finding any documents in the collection from that array of ID's. However, I double-checked the database and know that there are documents in the collection with ID's from the array.
const admin = require('firebase-admin')
....
let feedItems = db.collection(feedItemsCollection)
feedItemsList = feedItems.where(admin.firestore.FieldPath.documentId(), 'in', ['HPOorsSnbHpTYwwXxfWw']).get().then(snapshot2 => {
console.log(admin.firestore.FieldPath.documentId())
console.log("In feed Items")
//console.log(feedItemIds)
console.log(snapshot2[0])
//error happens on this line because snapshot2[0] returns undefined
console.log(snapshot2[0].data())
})
Snapshot2[0] returns undefined which I'm assuming means that no data was returned. I think I'm not properly calling documentId(), but don't know the fix.
There "maybe" two problems with your code. Follow both points to make sure things are working
Data inside snapshot2 maybe empty
You'll first have to fix your code to test this theory. You're not accessing data from snapshot2 correctly. To do it right, one way is this:
// `snapshot2` will have a `docs` property that you can leverage
const snapshot2Data = snapshot2.docs.map((doc) => doc.data());
.documentId() may not be doing what it's supposed to (as you said)
To test this theory, check if snapshot2Data is empty. Run :
console.log(snapshot2Data); // what do you get ?
If no, it's not empty and you got data back, then you're all set. Nothing more to do
If yes, it is empty, then run :
console.log(admin.firestore.FieldPath.documentId()); // what do you get ?
Did you get back a string? If no, then we have another problem. You'll need to take a closer look at your firebase-admin setup, as well.

Firebase Firestore: How to update or access and update a field value, in a map, in an array, in a document, that is in a collection

Sorry for the long title. Visually and more precise, I would like to update the stock value after a payment is made. However, I get stuck after querying the entire document (e.g. the selected one with title sneakers). Is there a way to actually query and update for example the Timberlands stock value to its value -1. Or do you have to get all data from the entire document. Then modify the desired part in javascript and update the entire document?
Here is a little snippet of a solution I came up with so far. However, this approach hurts my soul as it seems very inefficient.
const updateFirebaseStock = (orders) => {
orders.forEach( async (order) => {
try {
collRef = db.doc(`collections/${order.collectionid}`);
doc = await collRef.get();
data = doc.data();
//Here:const newItems = data.items.map(if it's corr name, update value, else just return object), results in desired new Array of objects.
//Then Update entire document by collRef.update({items: newItems})
} catch (error) {
console.error(error)
};
});
}
You don't need to get the document at all for that, all you have to do is use FieldValue.increment(), using your code as a starting point it could look like this:
collRef = db.doc(`collections/${order.collectionid}`);
collRef.update({
Price: firebase.firestore.FieldValue.increment(-1)
});
You can increment/decrement with any numeric value using that function.

How can I get a particular document data from fire store collection by ID?

I need to get data from collection based on Id but I'm unable to fetch details.
I have tried certain methods but none worked as expected.
Example 1
return this.db.collection("customers/", id).snapshotChanges();
It says to pass odd numbers of segment
My function
this.auth.getUserDetails(this.userid).subscribe(data => {
console.log(data);
});
Example 2
return this.db.collection('customers')
.doc(id)
.get();
What would be the better way to fetch and display data?
You can go like this:
// Assuming ID is passed as an argument.
this.db.doc(`costumers/${id}`).snapshotChanges();
The reason why you're getting problems is because you're using collection instead of doc.

Trying to get a snapshot of a variable from firebase gives me an error

Problem
In a social media app I am making with react native and firebase, I am trying to grab the number of comments a post has using the snapshot function of a variable I have saved on my servers, then I am going to add one to this variable when a user adds a new comment. My code to do so is right here:
firebase.database().ref('posts').child(this.state.passKey).update({
comments: firebase.database().ref('posts/'+this.state.passKey).child('comments').snapshot.val() + 1
})
When I actually run this code, I get an error saying:
Reference.child failed: First argument was an invalid path = "undefined".
Paths must be non-empty strings and can't contain ".","#","$","[", or "["
At first I thought this might be that the "this.state.passKey" wasn't actually passing the key, but putting in a key I copied from the server didn't fix the problem.
My Server
-
To get the comments of particular post you should do like this
let postId='someId'
postRef=`/posts/${postId}`
firebase.database().ref(postRef).once("value", dataSnapshot => {
comment=dataSnapshot.val().comments
});
It looks like you're expecting this bit of code to query the database:
firebase.database().ref('posts/'+this.state.passKey).child('comments').snapshot.val() + 1
Unfortunately, it doesn't work that way. There's no snapshot property on a database Reference object returned by child() or ref().
Instead, you'll need to query the database at that reference, then when you're called back with its value, you can apply it elsewhere.
var ref = firebase.database().ref('posts/'+this.state.passKey+'/comments')
ref.once('value', function(snapshot) {
// use the snapshot here
})

Mongo DB - Why my Users.findOne is Undefined?

I'm working on Meteor, trying to find some values from Mongodb collection.
here is the code:
var sameLogins = Users.findOne({login: 'a'});
console.log(sameLogins);
But it's returning and "undefined".
But record exists in collection:
So, can anybody tell what I'm missing?
Also, in mongo console - everything is working fine:
I was looking in Publish/Subsribe stuff, but i'm using autopublish module yet.
Thank you!
I will leave the answer for this issue for new users having the same problem.
If you're using autopublish package then you should be aware that it's publishing the result of .find() for every collection.
But, Meteor.users.find(), be default, will return only _id and profile fields, so documents in your Meteor.users client collection will have these two fields only.
The most easy workaround for this would be to create your own publication (allUsers, for example) and in it to return those fields you need:
Server:
Meteor.publish('allUsers', () => {
// check for Meteor.userId() is omitted, put it here, if needed
return Meteor.users.find({}, { fields: { ... } });
});
Don't forget to subscribe to it:
Client:
Meteor.subscribe('allUsers');
Update for Meteor:
Right now you are storing a cursor in your variable sameLogins. In order to retrieve the results you want, you must actually execute this query by either calling fetch(). What is returned from findOne without fetch is essentially an object that you could use to iterate over and find mongoDB documents - (called a collection cursor). The cursor is not your result itself.
Calling fetch would like something like:
Users.findOne({login: 'a'}).fetch()

Categories

Resources