In my flutter application I want to prevent users to enter their nominations after the cutoff date.
For example, there is an exam nomination with cutoff date 31st March 2020. I am inserting the nomination data from my flutter app to the Firebase database. In app I'm checking the current date should be before the 31st March and then only allow to enter the data. However if the user changes the mobile data to backward the the app will allow to enter the nominations for the exam.
I know if I write the Firebase Cloud Function and move my insert code there it will solve the issue. But I have lot of code that I will have to rewrite :-(. Is there any other solution that will allow me to know the actual current date? What if the internet is off?
Thanking you in advance
You could maybe write a small amount of backend code to read the Firebase server timestamp and use that to check the cutoff. See this code:
exports.currentTime = functions.https.onRequest((req, res) => {
res.send({"timestamp":new Date().getTime()})
})
I got this from this SO answer so don't ask me for more details :-)
How to save the current date/time when I add new value to Firebase Realtime Database
Not sure about how to handle the Internet off... but if you can't read the server date, they can't submit the results.
Your only option that doesn't involve writing backend code is to use security rules to restrict database writes based on the current date. What you will have to do is set up a rule on the collection that should be restricted, and it will have a line that looks something like this:
allow write: if request.time < timestamp.date(yyyy, mm, dd);
Where yyyy, mm, and dd are the components of the date. If you want something more specific, read the security rules API docs for timestamp functions - you will have to provide an time in epoch milliseconds. Note that timestamps in security rules are always measured in UTC.
Related
In my current application, I store a value in Firestore for each user something along the lines of this:
User1Doc - hasUsedFeatureToday = true
User2Doc - hasUsedFeatureToday = false
...
At the end of the day, I run a scheduled function that resets all of these to false. This was fine while my application was relatively small, but does not scale very effectively as I'm sure you can imagine.
Each user can only use this aspect of my app once per day, so the only time this field is read is when they try to use it.
I would like to change this system to store a timestamp in the user's document when they use the feature and then check if this timestamp is the same day (Europe/London time) if someone tries to use it again.
Does Firebase offer a way to get a "timezoned" timestamp like this and store/check it with the Firestore?
You can just store a timestamp (UTC). Whenever users logs in to your app, just check the timestamp and update the same. You can always use libraries like Luxon to get local time from the UTC time.
If you want to allow the user to update this timestamp only once, you can use security rules to restrict the same. However, user may try to prevent the timestamp from being updated at first place.
You can instead use Cloud Function to serve the data only when the user requests it. This will be better than updating documents of all users even if they won't be using the feature every day.
I made a game with JavaScript in which the user takes a specific amount of time to complete it. Then I want to create a document in a collection named scores on Firestone with that time. My problem is that the user can create an infinite amount of documents with a random time by simply copy & pasting the code and entering their own values. Is there a way that the user can only create once a document with the correct time at the end of the game? Here is the code that I used:
db.collection('score').add({
time: 122,
});
You have two requirements I think:
The user should only be able to create one document.
The time in the document must be the current time at the end of the game.
Allow only one document per user
The first one is easiest to do by using Firebase Authentication to sign the user in, so that they have an identity. If you don't want the user to enter any credentials, you can sign them in using anonymous authentication.
No matter how you sign them in, this gives them a unique UID (user identifier), which you can then use as the document ID:
let uid = firebase.auth().currentUser.uid;
db.collection('score').doc(uid).set({
time: 122,
});
So instead of calling add() (which generates a new document each time you call it), we create a document with the user's UID as its name. That way the user will always be writing to the same document.
You can then enforce that the user can only write their own document with Firebase's server-side security rules. See for an example of this, the documentation on content-owner only access.
Ensure the time can't be spoofed
To prevent the user from writing just any value they wish into the database, we can use Firestore's built-in FieldValue.serverTimestamp marker value. When you use this in your code, the Firestore server automatically writes in the current value from the server:
let uid = firebase.auth().currentUser.uid;
db.collection('score').doc(uid).set({
time: firebase.firestore.FieldValue.serverTimestamp(),
});
Here too, you can then use Firebase's server-side security rules to ensure that a malicious user can't pass their own value. To do that, compare the value that is being written (request.data.time) with the built-in variable for the current time (request.time).
I am creating a School exam application where I give some questions to the database(firestore) and I want to expire those data from the database after some specific time!! how to do this in firebase
Client-side centric:
Record a "timestamp" upon creation of the exam.
Make the client show the exam as "expired" if and when ("now" >= "timestamp + # of days or hours")
OR:
Server-side...
If you actually want to delete the data from the db or mark it as "expired", you can create a Firebase function.
Let's assume that when creating an exam/question, you're adding an "expiration_time" when that data is supposed to be marked as "expired" or be deleted altogether.
Have your Firebase function do the following:
Query data where the "expiration_time" is less than or equal to "now".
For each result, mark that data as "expired" or delete it altogether, depending on your use case.
After you test your function and you know it works, make it so that it's a "Scheduled Firebase function" (google it if you don't know, it's easy to set up) - for example, make it run every minute.
I'm planning to use firebase, but I have security related question.
My documents have creation_date property and it is filled with ServerValue.TIMESTAMP when document created.
Can I be sure that user will not reverse engineer my webapp to somehow insert fake date? And protect this field from future edits.
You can use the request.time variable in the security rules for validating the value of the timestamp. From the reference documentation:
The time variable contains a timestamp representing the current server time a request is being evaluated at. You can use this to provide time-based access to files, such as: only allowing files to be uploaded until a certain date, or only allowing files to be read up to an hour after they were uploaded.
// Allow a read if the file was created less than one hour ago
allow read: if request.time < resource.data.timeCreated + duration.value(1, 'h');
Many functions are provided to write rules using timestamps and durations.
I am working on a project where you book hotel reservations.In the add booking page, I have an input datetime-local where the user selects the date and the time of the booking.
I want to get the online time and not use the device time to disable the user from booking past datetimes.
I tried to get the server time Timestamp from Firebase but did not know how to work with it.
I want to know what is the best way to deal with this issue.
For firebase3, use firebase.database.ServerValue.TIMESTAMP
$scope.createdDate = firebase.database.ServerValue.TIMESTAMP
doc is available here
and for date time picker go for this code.