Is there a way to configure the Firestore timestamp outputs? - javascript

I'm using Firestore to keep timestamps such as this log output:
{
my_timestamp: Timestamp { seconds: 1676783325, nanoseconds: 209000000 },
product_name: 'Android'
}
I'm reading the values in my web app like this:
...
const result = []
productDocs.forEach((productDoc: DocumentData) => {
result.push({ id: productDoc.id, ...productDoc.data() })
})
return result
...
But I get an error:
Server Error
Error: Error serializing `.productDoc[0].my_timestamp` returned from `getStaticProps` in "/[pid]".
Reason: `object` ("[object Object]") cannot be serialized as JSON. Please only return JSON serializable data types.
It seems to me that the Timestamp object is not easily accepted as part of the object. My solution is to iterate through each Object.entries(productDoc).forEach(productData)... and reformat the Timestamp object and then push on an array.
This seems like a manual way to go about this so I'd like to make sure I'm parsing the timestamp object properly and I'm not missing some way where I can just read the whole result from Firebase as an object with doing nothing to the timestamp.
It seems How do I convert a Firestore date/Timestamp to a JS Date()? is the only way where I have to take the object apart and convert the values.
I didn't see a way to do this on https://firebase.google.com/docs/reference/js/firestore_.timestamp other than just converting the Firebase object.

Using the DocumentSnapshot type should solve your problem:
const result = []
productDocs.forEach((productDoc: DocumentSnapshot) => {
result.push({ id: productDoc.id, ...productDoc.data() })
}
A DocumentSnapshot contains data read from a document in your Firestore database while a DocumentData is to be used with the setDoc() method.

Related

Passing Dynamic Mongoose query into db.collection.find()

I have a client side application that I would like to have the ability to specify arbitrary queries to MongoDB through a server side call to a query function.
I have tried multiple arrangements on both my client and server to try to make this work but I can't seem to figure out the correct way to go about this.
This is an example request that my client would send (although the goal is for the query property to be any valid query that one could hardcode on the server side):
{
"collectionName": "abilities",
"query": "{\"_id\":{\"$in\":[5,{\"$oid\":\"619f97d1d977f089ac559368\"}]}}"
}
On the server side, I've parsed the query with EJSON to try and get it to a state where I can pass it into the db.collection.find() method but the return type is not compatible (I recieve: EJSON.SerilizbleType vs I need: Filter<Document>)
Another thought I had was to stringify the EJSON result and then convert it to JSON through JSON.parse(). If I console.log() the result, I get the following:
{ _id: { '$in': [ 5, '619f97d1d977f089ac559368' ] } }
Passing that into the find() method produces no results.
If I console.log() the parsed text, I receive the following:
{
_id: { '$in': [ new Int32(5), new ObjectId("619f97d1d977f089ac559368") ] }
}
Which shows that the JSON conversion is losing the type, which is important when constructing the query.
Thoughts on how I may go about this?

Using MongoDB Stitch webhook service function, how can I convert the returned "insertedId" to string?

I'm creating MongoDB Stitch http services (using the 3rd Party Services > Incoming Webhooks > Function Editor) for a simple CRUD application and I am trying to insertOne() document and then return the document id as a string.
The insertion works as expected and I await the result and store it in a variable.
const result = await collection.insertOne(payload.query)
const id = result.insertedId
The problem is trying to convert this id to string. I'm guessing it's due to my lack of understanding the MongoDB Extended JSON and BSON types, etc. I've read all parts of the documentation that I thought could provide a solution here.
I've tried the following to convert the return value to a string:
id.toString() // logs as a string, but is an object { $oid: '507c7f79bcf86cd7994f6c0e' }
id.valueOf() // logs as a string, but is an object { $oid: '507c7f79bcf86cd7994f6c0e' }
id['$oid'] // undefined
Object.values(id.insertedId) // throws error: {"message":"'values' is not a function"}
id.str // undefined
result.str // undefined
Not sure what else to try and would really appreciate if someone can point me in the right direction here to provide a solution.
Thank you in advance.
Found a solution after noticing this section of the documentation:
MONGODB STITCH > Functions > Reference > JSON & BSON
const result = await collection.insertOne(payload.query)
const id = JSON.stringify(
JSON.parse(
EJSON.stringify(result.insertedId)
).$oid
).replace(/\W/g,'');
Seems a bit hacky just for getting the id of the document into a string, but it will work for now.

Receiving error when trying to use JSON.parse from internal storage data

My classmates and I are receiving the following error message when trying to use JSON.parse with data from internal storage. The code is given to us by our instructor so not sure what the issue is.
internal storage should hold nothing and initialize "pageViews" with 0 or if there is data in internal storage it should be an array.
Uncaught SyntaxError: Unexpected token o in JSON at position 1 at
JSON.parse () at HTMLDocument.addPageView
HERE IS OUR CODE.
const pageViewsKeyName = "pageViews";
function addPageView() {
let pageViews = localStorage.getItem(pageViewsKeyName);
let arr = [];
if (pageViews && pageViews.length > 0) {
// get the array stored in local storage at pageViewsKeyName
arr = JSON.parse(pageViews);
// now we're able to insert an item in the page view data
let newPageData = {
"path": window.location.pathname,
"timestamp": moment()
};
// now add new page data to the array
arr.push(newPageData);
// finally, we want to update our storage with the most up to date array
localStorage.setItem(pageViewsKeyName, arr);
}
}
JSON.parse is used to parse the string JSON value as JSON object. Looks like the pageViews already contains JSON object. Therefore you don't need to parse it. You can console.log(pageViews) to confirm that.
Yes, console.log(typeof PageViews) and check out what is it's data type.
If it's an arry:
arr.push(PageViews[0]); // TODO for-loop to push all views into arr
If it's an object:
arr.push(PageViews)

Not able to access Object values returned from a web service in React

Here are whats returned in response when hitting the service:
{
"2019-04-20":{
"fare":0,
"IsPricePos":false
},
"2019-04-19":{
"fare":0,
"IsPricePos":false
},
"2019-03-27":{
"fare":45,
"IsPricePos":true
},
"2019-03-26":{
"fare":9,
"IsPricePos":true
},
"2019-03-25":{
"fare":23,
"IsPricePos":true
}
}
Using the below code for hitting web service and getting a response:
fetch("/somepath/somefurtherpath/" + src + "/" + dst)
.then(response => response.json())
.then(result => Object.assign(newObj, result));
I am using fetch API as shown.
1) JSON.stringify(newObj) returns {} i.e. empty object string.
2) Not able to do JSON.parse(newObj) as it says its already an object.
3) Object.keys(newObj) returns an empty list.
The console.log(newObj) gives below (opening the object printed in console):
{}
2019-03-21:
IsPricePos: true
fare: 45
__proto__: Object
2019-03-22: {fare: 45, IsPricePos: true}
2019-03-23: {fare: 45, IsPricePos: true}
2019-03-24: {fare: 23, IsPricePos: true}
I need to access data in JSON and do operations on it. e.g. keys and its values.
I need to access values of fare or IsPricePos for any given dates as keys.
I tried accessing the values as newObj."2019-03-25".fare, but did not work too.
What is the best way to do this? Does React have any specific issue with this type of situation?
I tried hardcoding an object and accessing values using JavaScript, it works well. But this situation is an issue.
Please help. Thank you.

How to get all records from collection using createddate field in meteor js application

I have a sample transactions collection similar to below
[
{"_id":"123","createddate":"2017-07-24T09:43:31.028Z"},
{"_id":"124","createddate":"2017-07-25T09:43:31.028Z"},
{"_id":"125","createddate":"2017-07-26T09:43:31.028Z"},
{"_id":"123","createddate":"2017-07-28T09:43:31.028Z"},
{"_id":"126","createddate":"2017-07-27T09:43:31.028Z"}
]
But in my production we have around 50-60 records for each date(createddata field).I need to get all the records for a particular date based on selection then download that.
I used below:
Meteor.methods({
gettransactionsdata:function(){
let transactionRecord = transactions.find({"createddate":"2017-07-26"});
return transactionRecord;
}
});
When I try calling above function it is returning transactionRecord as undefined. How can we do this?
You're storing dates as strings instead of dates which is not recommended for numerous reasons. For a simple day you can do a $regex search to find the strings that begin with the day you're looking for:
transactions.find({ createddate: { $regex: /^2017-07-26/ }});
You could also just pass that date string to your method for a bit more flexibility:
Meteor.methods({
gettransactionsdata(dateStr) {
return transactions.find({ createddate: { $regex: new RegExp('^'+dateStr) }});
}
});

Categories