Since recently, Firestore returns timestamps not as Date objects, but as Timestamp objects. Meaning, after every query you have to do something like this:
// Old:
const date = snapshot.get('created_at');
// New:
const timestamp = snapshot.get('created_at');
const date = timestamp.toDate();
I have objects with multiple timestamps stored in them, and I am forced to convert every of these timestamps individually before I can do anything with my object. What I do now is the following:
let user = // get user from firestore
user.created = user.created.toDate()
user.lastUpdated = user.lastUpdated.toDate()
user.foo.foo.foo.foo.fooDate1 = user.foo.foo.foo.foo.fooDate1.toDate()
user.foo.foo.foo.fooDate1 = user.foo.foo.foo.fooDate1.toDate()
...
user.foo.fooDate99 = user.foo.fooDate99.toDate()
Is there a way around that?
I have to do this with all of my documents, even if I don't need the timestamps to be converted, since various dependencies (e.g. devalue) break with a "Non-POJO" errors when there are raw firestore timestamps in my object.
Is there an option to directly convert all timestamps of a document to normal Date objects, or is the manual way the only option?
There's no simple option you can toggle to make this happen.
If you don't want to manually change them all, you could write some code to recursively descend all the properties of all your objects, check which ones look like Timestamp objects (for example, it has a toDate function), and make the conversion if so.
Related
I'm trying to write to Firestore all the prices from different stocks. Structure should look something like this (although this might not be the best fitted for it, still thinking of it as in SQL) :
const d1 = new Date();
const result = d1.getTime();
console.log('Epochtime',result);
database.collection("stock1").doc("exchange1").collection(date).doc('prices').set({"price":"price_value"})
Now the problem is that I can't create a collection with a name that's a variable that contains date. I tried all the different types of it and I presumed that epoch time should work, as this is a number like: 1636213439908. I always get the error: Value for argument "collectionPath" is not a valid resource path. Path must be a non-empty string. Although the exact same variable can be written as a value in a collection. So not sure what am I doing wrong here.
Document IDs in Firestore must be strings, so you'll have to convert the data to a string. While date.toString() will work, I highly recommend using a ISO-8601 format for the dates, such as date.toISOString(). These formats are designed to be both humanly readable and machine sortable.
Let's say I have a collection of articles:
var articlesRef = new Firebase("https://example.firebaseio.com/articles");
$scope.articles = $firebase(articlesRef);
I want to add a few articles with a new Date() priority:
$scope.articles.$add(newArticle1).$priority = new Date();
$scope.articles.$add(newArticle2).$priority = new Date();
$scope.articles.$add(newArticle3).$priority = new Date();
How do I fetch these articles and sort by the Date priority?
How do I query a range of articles from X-Date to Y-Date?
How do I retrieve the values of those priorities?
If you are trying to order posts by time, I recommend not using Date() and only rely on $add. $add automatically creates chronologically ordered lists of items. In the absence of priorities, Firebase automatically orders items by their key names.
To fetch the articles in chronological order, simply use the orderByPriority filter, eg: <ul ng-repeat="article in articles | orderByPriority">.
Querying a range from a specific data becomes trickier - if you know the key name for the article you want to start the range at, you can just pass that to startAt. $add returns a Firebase reference, and you can get the key name via .name().
For example, the following snippet will create a window starting at the article just added and upto 10 articles after it:
var justAdded = $scope.articles.$add(newArticle);
var query = ref.startAt(justAdded.name()).limit(10);
For a comprehensive solution where you need to be able to query by any time across all articles, you might consider storing a time for each item added via $add. I'd again avoid using Date() becaue client-side times cannot be trusted, but instead use Firebase's server side timestamps: https://www.firebase.com/docs/javascript/servervalue/TIMESTAMP.html which are more reliable. For instance, you might store the time at which a particular article was added so you can later cross-reference a given time with an article ID auto-generated via $add.
I wish to store if a specific date is loaded via Javascript. How this boolean is saved/accessed has no difference, however I'm not sure as to what the best solution is performance-wise.
I could know I could store it like this and loop through each object, however I guess this wouldn't really be efficient.
var loaded = { {d:23, m:11, y:2012}, {d:24, m:11, y:2012} };
Another idea I have is to store this in an array, like so:
loaded[2012][11][23] = true;
But I'm sure there are better ways to accomplish this, so I'd appreciate any guidance
Unless you have to list available years, available months or available days, you could always use an Object as a dictionary for storing dates as UNIX timestamp numbers (which you can convert to and from Date objects) or "YYYYMMDD" strings.
I am using local storage to store user entries and am displaying the entries on another page. I need a way to sort them based on the most recent date and time of edit. Is there a way to do this with HTML5. If not, what's the easiest/most effective way to do so?
Thanks for the inputs.
If your keys/values have an inherent order to them (alphabetical, numerical, etc), then putting a timestamp in them may be superfluous. Although the Storage object has no sort method, you can create a new Array() and then sort that.
function SortLocalStorage(){
if(localStorage.length > 0){
var localStorageArray = new Array();
for (i=0;i<localStorage.length;i++){
localStorageArray[i] = localStorage.key(i)+localStorage.getItem(localStorage.key(i));
}
}
var sortedArray = localStorageArray.sort();
return sortedArray;
}
The disadvantage to this is that the array is not associative, but that is by nature of the JavaScript Array object. The above function solves this by embedding the key name into the value. This way its still in there, and the functions you'd use to display the sorted array can do the footwork of separating the keys from the values.
You've got to pair the timestamp with the stored value somehow, you can create a wrapper object for each value and store the value and the timestamp in a single object. Assuming you have a value myvalue you want to store with reference myref:
var d=new Date();
var storageObject = {};
storageObject.value = myvalue;
storageObject.timestamp = d.getTime();
localStorage.setItem(myref, JSON.stringify(storageObject));
On the other page you then need to rehydrate your objects into an array and implement your compareFunction function.
Your other option would be to use Web SQL Database and Indexed Database API which lets you more naturally store and query this sort of multifaceted info, but you would probably have to create some sort of abstract wrapper to make things work easily cross browser.
I need to create a function to filter data according to time.
I have a table of flights with departure time in related rows, what i need is, i will put to time filter fields to my form, for hiding flights before and after selected time. In other words, flighs bettween selected time interval will be visible.
I have no problem with getting time info from table and my inputs, but i do not now how to compare them.
I use jquery.
No need for jquery on this one. Just plain old javascript.
The easiest way is to just convert the date objects to unix time using getTime method (I think that is the name). Then just do a greater/less than comparison to see if the values are within the range.
The easiest and fastest way of doing client side data manipulation (sorting, filtering, grouping) is jOrder.
In your case, I assume the data looks something like this: (date1 and date2 being date objects)
var data = [{flight: '776', departure: date1}, {flight: '51', departure: date2}];
First thing, create a jOrder table out of the array, with index on departure time.
var table = jOrder(data)
.index('departure', ['departure'], {grouped: true, ordered: true});
Then, you can easily select the row with dates in the specified range.
var hits = table.where([{ departure: {lower: datelow, upper: datehi}}], {mode: jOrder.range});
Finally you can rebuild or modify the UI objects according to the hits.
jOrder is available at http://github.com/danstocker/jorder.