Firestore limit read snapshot by current time - javascript

I want to display the last 10 messages of a conversation. Then as the conversation progresses, obviously, I need to show those messages as well:
I am doing something like this:
//function a
db.collection("conversations/" + messageID + "/messages").orderBy("timestamp", "desc").limit(10).
get().then(function(querySnapshot) {
const time = Date.now();
//call function b and pass time as a parameter
//function b
db.collection("conversations/" + messageID + "/messages").where("timestamp", ">=", time)
What security rules will allow me ensure that time in function b is somewhat close to the current time?
Thanks!

You can use request.time for when the specific document was created, which is type of Timestamp, as stated in the Rules documentation.
I found this StackOverflow post which might help as well.

Related

Google search callback function

Hello I am new to programming and came across a task abour google search api. I went through the docs and wonder what does the code below will do? below will do.
const myWebSearchStartingCallback = (gname, query) => {
const hour = new Date().getHours();
return query + (hour < 12 ? ' morning' : ' afternoon');
};
window.myImageSearchStartingCallbackName = myWebSearchStartingCallback;
Many thanks.
From the docs:
The example search starting callback in Example Search Starting Callback adds either morning or afternoon to the query depending on the time of day.
A callback is a function that gets called at a later point in time, for example when the user of the website takes some action. In this case, the callback gets called when the user enters a search query, and this callback modifies the search query to add either "morning" or "afternoon" to the end of that search depending on the user's current time.

How to I use my firebase variables as an integer?

I have a simple program that you can post/accept games then report back the score. I am having an issue of updating the score as information stored in firebase is stored as a string. How do I take my score as an integer to add to it?
if (selfScore > oppScore) {
var ref = new Firebase('taken out');
var selfRef = firebase.database().ref("users/" + (selfKey));
selfRef.update({
"tScore": ("tScore" + 3)
});
}
Ideally, the score would take the previous score and add 3 but this is not the case. I'm new to firebase so if this is obvious, my bad. An edit to clarify when I remove tscore and just have tScore: +3 it just changes tScore to 3, it doesn't add it.
You cannot make some operations on field value within the update() method. So you should first read the value from the database and then update the record with the new value.
The best approach is to use a transaction for such operation, which will automatically do the read/write operation and, in addition, ensure "there are no conflicts with other clients writing to the same location at the same time".
You would then do as follows:
var selfRef = firebase.database().ref("users/" + selfKey + "/tScore");
selfRef.transaction(function(currentValue) {
return currentValue + 3;
});

Using Javascript I want to be able to run a particular task at a certain time

I know javascript is not the best way to go about this. I know that I would have to have the browser up and always running. I would normally do something with Python. This was a specific requests of me and i'm not very proficient with javascript. That being said.
I want the user to be able to set a time using inputs. Once these inputs have been set I want the browser to check for the time specified. Once the time occurs I want it to execute a command.
Her is what I have so far:
<html>
<body>
<p>Enter Time to start dashboard</p>
<p>Hour</p>
<input id="strthour">
<p>Minute</p>
<input id="strtmin">
<button onclick="setTime()">Submit</button>
<script>
var hr = 06; //default time of 6am to run
var mn = 00;
function setTime() {
hr = strthour.value;
mn = strtmin.value;
}
window.setInterval(function(){ // Set interval for checking
alert(hr+mn);
var date = new Date(); // Create a Date object to find out what time it is
if(date.getHours() === hr && date.getMinutes() === mn && date.getSeconds() === 0){ // Check the time
alert("it worked")
}
}, 5000); // Repeat every 60000 milliseconds (1 minute)
</script>
</body>
</html>
I am able to change the global variables, but I am unable to get window.setInterval to recognize the changes. Any advice?
Here is a link to a JSFiddle I made.
There are several issues with your code, which various people have pointed out.
Walker Randolph Smith correctly notes that date.GetHours() and date.getMinutes() will both return numbers, while the values returned from strthour.value and strtmin.value will be strings. When JavaScript compares these two, it will always evaluate to false. To fix this, try running the user input through parseInt, as in hr = parseInt(strthour.value, 10);. The 10 is important because it tells parseInt to create a number of base 10 (you don't need to know what that means, just make sure to include the 10).
Your need for the seconds to match is probably unnecessary, and does not match up with the interval you chose. TheMintyMate made this correction in their code snippet by simply removing the comparison for seconds. If you really need to make sure the seconds match up perfectly, pick an interval of less than 1000 milliseconds, so you know it is going to check at least once every second, guaranteeing that you will run the check on that 0th second of the desired time.
You could run into some trouble with single digit minutes if you try to compare them as strings, rather than converting to numbers as recommended in point 1. The .getMinutes() method will return a single digit 0 for a time like 6:00, while your example is implicitly prompting the user to enter in two digits for that same time. Again, you can avoid this issue entirely by using parseInt as recommended in point #1.
I do have to throw in a plug for using Cron jobs for running tasks on a known schedule like this. I know you said the user requested JS in this case, so they may not apply for this specific situation. Since you didn't mention Cron jobs though, I have to include them here to make sure you and future readers are aware of them, because they are designed for exactly this situation of running a task on an automated schedule.
Good luck!
You are not correctly referring to the inputs, and you also have a syntax error with your alert. Below is my suggested fix (working):
<p>Enter Time to start dashboard</p>
<p>Hour</p>
<input id="strthour">
<p>Minute</p>
<input id="strtmin">
<button onclick="setTime()">Submit</button>
<script>
var hr = 0;
var mn = 0;
function setTime() {
hr = parseInt(document.getElementById("strthour").value);
mn = parseInt(document.getElementById("strtmin").value);
console.log("set time: "+hr+":"+mn);
}
setInterval(function(){
var date = new Date();
if(date.getHours() == hr && date.getMinutes() == mn){ // using == not ===
alert("it worked");
}
}, 10000);
</script>
Note: You should also parseInt() the values to ensure they are valid numbers.
if(date.getHours() === hr && date.getMinutes() === mn && date.getSeconds() === 0){ // Check the time
alert("it worked")
}
This will compare a string to an int and always be false.
either perform parseInt(date.getHours()) or use ==
It's not because setInterval doesn't recognize the change, you actually don't modify the values.
If you open the javascript console on jsfiddle page you'll see "Uncaught ReferenceError: setTime is not defined".
It will work if you define you setTime like this:
window.setTime = function() {
hr = strthour.value;
mn = strtmin.value;
}
This is because JSFiddle doesn't run your code directly, but wraps into
<script type='text/javascript'>//<![CDATA[
window.onload=function(){
... // you code here }
}//]]>
Here is a modified JSFiddle which just "it worked" for me.
Update - some notes, as mentioned in other answers:
The use of '===' is also an issue, hr/mn are strings, so you need '==' or convert hr/mn to integers
Expression like strthour.value in setTime works in JSFiddle. I am not really sure why, but it works. In the "real world" it should be something like document.getElementById("strthour").value
Update 2 - why does strthour.value work (vs document.getElementById("strthour").value)?
This was actually a surprise for me, but it looks like all major browsers put all elements with id into window object. More than that, it is actually a part of the HTML standard (although it is not recommended to use this feature):
6.2.4 Named access on the Window object
window[name]
Returns the indicated element or collection of elements.
As a general rule, relying on this will lead to brittle code. Which IDs end up mapping to this API can vary over time, as new features are added to the Web platform, for example. Instead of this, use document.getElementById() or document.querySelector().
References:
HTML 5.1 - 6.2.4 Named access on the Window object
Do DOM tree elements with ids become global variables?
Why don't we just use element IDs as identifiers in JavaScript?
I think you should use ">=" operator, because you don't know if it's gonna be EXACTLY that time.

Checking how much time passed from creating objectid in mongodb

I'm building an app that allows the user to reset his password.
The process is really simple .The user enters his email address and I sending him a link with the number of the new objectid that was created.
For exemple -> /reset-password?x=55555444475d41a000001.
After clicking the link he reaches other page and then I want to check if 24 hours have passed from the time he got the link?and yes i know there is function called "getTimestamp" but how to use it..?
get: function (request, response) {
???????
},
You can set a "creation_date" property in your object when you create it, like this:
obj = {
id: "xxxxxx...",
creation_date: new Date()
...
}
Then you store the object somewhere in your server, and then when the user opens the link with the id of the object you will do something like this to check if the object has been created more than 24hours ago:
var now = new Date();
if (now - obj.creation_date > 86400000) {
// more than 24h (86400000ms = 24h)
// do something
}
Actually reading the JavaScript API docs for ObjectId might help.
Checking wether 24 hours have passed since the creation of the object should be as easy as
var now = new Date();
/* Subtract the milliseconds a day lasts from the current time.
* If the timestamp of the ID converted to msecs after epoch is smaller
* the ObjectId was created before that.
*/
if ( myId.getTimestamp() < ( now.getTime() - 86400000 ) {
console.log("24 h have passed since creation");
}
else {
console.log("24 h haven't passed since creation");
var passed = new Date( now - myId.getTimestamp() );
console.log(passed.getUTCHours()+":"+passed.getUTCMinutes()+" have passed.");
}
Note: I downvoted your question as it would have been easily solvable by googling "MongoDB ObjectId getTimestamp JavaScript api", you didn't show any sign of working on the problem yourself and didn't bother to ask a specific question. May I politely suggest reading ESR's How To Ask Questions The Smart Way, especially the chapter about StackOverflow?

Multiple javascript timeouts - problem with live data fetching

I am building a real-time system which (with a use of websockets) updates a table with live data of different frequencies (can be 3 times per second, can be once every 2 seconds - dependant on the type of data).
I am currently struggling to find a way of letting the user know when a particular field has not been updated in the last 5 seconds. That is, if no new data is fetched, I shouldn't keep the old value there, but rather change it to '--' or something similar.
After a long way to the javascript, final function which updates fields looks like that (extremely simplified):
function changeValue(data){
var fieldId= data.fieldId;
var value = Math.round(data.value);
$('span#'+fieldId).text(value);
}
This function gets called each time a field needs to be changed. I've got between 2 and 40 different fields (dependant on the user) that are changed.
What is the best way of setting timers in order to change the values of the fields to '--' every 5 seconds, if no update has been made?
I would be really grateful for some tips,
Thanks,
Karol.
Since you want to indicate timeout on a per-field basis, you have two obvious options:
Have a global interval timer that ticks over fairly frequently and looks through all of your fields for a timeout.
Have independent timers for each field which just deal with that field.
I think on balance I prefer (1) to (2), because we're only dealing with one interval timer then and it makes the housekeeping simpler.
Since IDs in documents must be unique, we can use your field ID values as a key in a hash (an object) to store last updated times. This is kind of a spin on the previous answer but works on a per-field basis. So here's how we'd set those last updated times:
var lastUpdatedTimes = {};
function changeValue(data){
var fieldId= data.fieldId;
var value = Math.round(data.value);
$('span#'+fieldId).text(value);
lastUpdatedTimes[fieldId] = new Date().getTime();
}
Then you set up an interval timer to check each of them.
function checkFieldsForTimeout(){
var now = new Date.getTime();
// For each ID in lastUpdatedTimes, see if 'now minus
// last updated' is > 5000 and is so, set the field
// text to '--' and remove that entry from the last
// updated list with "delete lastUpdatedTimes[itemId]".
}
Should a timed-out field spring back to life, the "--" will be replaced by some real text again.
By deleting the last updated time from "lastUpdatedTimes" whenever we put "--" into a field, we make sure that the interval timer isn't wasting time processing fields that have already been timed out.
This answer was extended to handling multiple fields after the comment by #Andrew (please see also his answer).
Introduce a property updatedTime, which holds the last time the data was updated, in each data. A periodic timer checks updatedTime for all data and updates the text field if appropriate. The check has to be twice as often as the detection period. Your function changeValue() updates updatedTime and the text field.
function checkData() {
var now = new Date.getTime();
for "each data" {
if (now - data.updatedTime >= 5000) {
var fieldId = data.fieldId;
$('span#'+fieldId).text('--');
}
}
}
function changeValue(data) {
var fieldId = data.fieldId;
var value = Math.round(data.value);
$('span#'+fieldId).text(value);
data.updatedTime = new Date.getTime();
}
// Install periodic timer to check last updates:
setInterval(checkData, 5000 / 2); // interval = half the required detection period

Categories

Resources