Can't update firestore document array field with timestamp - javascript

I want to update document but when I try to put serverTimestamp(), document just doesn't updates:
await updateDoc(ref, {
'process.votings': arrayUnion({
finished: false,
timer: {
time: 60,
finishedAt: null,
startedAt: serverTimestamp()
},
votes: [],
winner: null,
candidates: candidates.map(candidate => candidate.id),
question: null
})
})
When I don't put serverTimestamp() everything works just fine.

serverTimestamp() does not work inside an array, so what you're trying to do isn't currently possible.
See also:
https://github.com/firebase/firebase-js-sdk/issues/1849#issuecomment-500031383
Adding a Timestamp to a nested object in Cloud Firestore
How to pass admin.firestore.FieldValue.serverTimestamp() to the update() method, using CloudFunction coded in TypeScript
You might want to consider an altnerative way to model your data, possibly by using separate documents in a nested subcollection rather than an array field in a single document.

Related

How to get references data on firebase

i want to ask something. why when im trying to get the reference firestore data, the value was print out like this. and i dont understand what this values mean, and how to use this.
{
_key: { path: { len: 2, offset: 0, segments: [Array] } },
converter: null,
firestore: { app: [FirebaseAppImpl], databaseId: [ie], settings: [Yc] },
type: "document",
}
how to get the reference data and return the proper data from firestore ?
this is what my references looks like:
When you get the value of a reference field, you get back a DocumentReference object. If you just want to get its path, like is shown in your console screenshot, you can read the path property of the DocumentReference.
If you want to get the data from the referenced document (so from the warehouse), you can call get() on the DocumentReference, same as you'd do for a DocumentReference that you'd have constructed in another way. For more examples of that, see the documentation on getting a document.

Updating nested MongoDB document object

Hello there, a quick MongoDB mixed with some Discord knowledge question:
So currently, I want a formation for my MongoDB Document similar to the following:
channels: {
utility:{
suggestions: String
},
logging: {
main: String,
channel: {
channelCreate: String,
channelDelete: String,
channelUpdate: String,
},
role: {
roleCreate: String,
roleDelete: String,
roleUpdate: String,
}
}
This saves channel IDs so users can decide where each event will be logged. I have this set up in the schema and all good, but when I do findOneAndUpdate I don't know how to edit a single field; for example, let's say I want to edit roleDelete which is inside channels.logging.role how would I do that? because doing
await doc.updateOne({channels:{logging:{role:{roleDelete: IDHERE}}}});
It does not work. In fact, it screws everything up and replaces everything within channels to the value given, so how would I go around actually updating ONE value without messing with everything else? Thank you so much for your attention and participation.
This is using NodeJS Mongoose NPM Package btw.
you need to use $set operator. you can find details on https://docs.mongodb.com/manual/reference/operator/update/set/index.html
doc.updateOne({ _id: ID }, {
$set: {
channels.logging.role.roleDelete: IDHERE
}
}
So I solved this by doing the following:
await doc.updateOne({ 'channels.logging.role.roleDelete': IDHERE}, { new: true, upsert: true, setDefaultsOnInsert: true });
This updated the value if it existed and created it if it didn't exist. Using the above methods uses $set internally. (Read more here)
Feel free to ask if I didn't make myself clear

In mongoDB, how do I get the id of an object created using insertOne() using async / await?

So I am creating a user object and inserting it into my mongo database using async / await.
Like so:
await db.collection('users').insertOne({
name: 'testName',
age: 20
});
console.log('new user created');
I would like to get the Id from the object I have just added. I am currently doing this like so:
const newUser = await db.collection('users').insertOne({
name: 'testName',
age: 20
});
console.log('new user created');
console.log(newUser.ops[0]._id);
This works as I would like it to but it doesn't seem like the cleanest way to do this. Is there a better way to get the newly created object's id using async / await?
Here is your answer:
insertOne Returns: A document containing:
A boolean acknowledged as true if the operation ran with write concern or false if write concern was disabled.
A field insertedId with the _id value of the inserted document.
Example:
{
"acknowledged" : true,
"insertedId" : ObjectId("56fc40f9d735c28df206d078")
}
Documentation HERE

Using Firestore, can you update and add to a sub-collection using a single update call?

I see that there is an example that calls update() and updates nested fields with firestore. Can you do a similar thing that does an update and adds to a subcollection instead?
e.g. we change this example from favorites being an object hash to a subcollection
var frankDocRef = db.collection("users").doc("frank");
frankDocRef.set({
name: "Frank",
favorites: { food: "Pizza", color: "Blue", subject: "recess" },
age: 12
});
to
frankDocRef.set({
name: "Frank",
favorites.add({ food: "Pizza"}), // I know this is probably the wrong syntax
age: 12
});
Would I create a batched write or a transaction because it goes across a single document and a sub-collection document separately?
Firestore doesn't offer an API to update multiple documents (no matter where they live) in a single call to set() or update() on a document reference.
You should do a batch write instead if you want to update multiple documents atomically. You only need a transaction if you need to read the value of a document before updating it (for doing things like incrementing a count).

Mongoose Schema extend timestamp to have new properties (username)

I´m using MongoDB and mongoose for a project that needs to track data creation and changes. The requirements are that I need to keep track of records creation and changes including the date/time and the application user (not the OS user) who did it.
I´ve seen the mongoose timestamps option that would solve my date/time issue, but is there a way to extend it to include extra properties, where I´m gonna be adding the application username ?
If not, is there a single place where I can write a function that will be called on every creation/update so that I can include/modify these fields ?
Today I´m insering these properties on every model like below, but I would like to move all of them to a single place.
var companySchema = mongoose.Schema({
name: {
type: String,
index: true
},
phone: {
type: String
},
deleted: {
type: Boolean
},
createdAt: {
type: Date
},
createdBy: {
type: String
},
updatedAt: {
type: Date
},
updatedBy: {
type: String
}
});
How would be the best approach for it ?
I would approach it by creating two models, one for each Data created, one for each Data Changes.
Data created which will have 6 fields one is createdBy, createdAt, and one will be a field with an array of reference id of Data Changes, deletedBy, deletedAt, deletedFlag.
Data Changes will have fields dataID which will have reference id of data created, updatedBy and updatedAt.
This way it will be easy to keep track of when it was created when it was changes and when it was deleted.
PS: You can remove either of Array in Data created model or dataID ref id in Data Change mode, it was just me being extra cautious while binding.

Categories