How to get current timestamp with Firebase react native? - javascript

Alright I've followed this question verbatim Firebase TIMESTAMP to date and Time and am posting to my Firebase database like this:
function storeUserInfo(username, industry, role, color) {
if (username != null && industry != null && role != null && color != null) { //use for errors later
let timestamp = firebase.firestore.FieldValue.serverTimestamp();
let push = firebase.database().ref('users').push();
push.set({
name: username,
industry: industry,
role: role,
color: color,
date: new Date(timestamp.toDate()).toUTCString()
});
}
}
This gives me the error: timestamp.toDate() is not a function
Ive tried several other methods like Firebase.ServerValue.TIMESTAMP but need to get the current formatted date for Firebase database. How can I do this?

You have a couple of things going wrong here. Firstly, you're trying to write to Realtime Database (via firebase.database()), but you're trying to use Firestore's timetamp with it. Firestore and Realtime Database are different databases with different APIs. A Firestore timestamp would not be helpful to you here.
If you want to get a date as reckoned by the client machine's clock, simply call new Date() with no arguments.
push.set({
name: username,
industry: industry,
role: role,
color: color,
date: new Date().toUTCString()
});
I suggest actually just storing an integer instead of a formatted string - it will probably be easier for you in the long term.
If you want to write an integer value based on the database server's sense of time, you would do this instead, using ServerValue.TIMESTAMP, which gets an actual integer value as soon as the write hits the server:
date: firebase.database.ServerValue.TIMESTAMP
If you were actually just hoping to get a server timestamp from Firestore's Timestamp API, that's not possible, because the server timestamp can only be calculated on the server. The error is telling you that there is no toDate() method available on the FieldValue type object returned by FieldValue.serverTimestamp(). It doesn't return a Timestamp. It returns a token that you can provide to Firestore that interprets the timestamp on the server and not in the client app. You should provide this token directly to Firestore if you want the server's timestamp in that field:

Related

firebase timestamps not serverside created

I have a chat app in react native using firebase and it is crucial to me that the timestamps are all synchronised and created serversided, not from the client. Clients can have different times depending on the settings on the mobile phone.
I tried out following function to prove my point:
const comparetimes = async () => {
const timezone1 = firebase.firestore.Timestamp.now();
const timezone2 = (firebase.firestore.Timestamp.now()).toMillis();
const timezone3 = Date.now();
console.log(timezone1);
console.log(timezone2);
console.log(timezone3)
}
What shocked me is the result of this function:
{"nanoseconds": 79000000, "seconds": 1641054839}
1641054839080
1641054839080
Apperently the firebase timestamp is the exact same as Date.now() which is a direct timestamp taken from the mobile phone, and therefore unaccurate.
What can I do to have timestamps not created by the client but by the server, in this example firebase? Do I need to checkout some APIs or is there something I miss here?
When you call Timestamp.now(), it really is just taking the timestamp on the client device. That's expected.
Read the documentation on how to use server timestamps. You must use the token value returned by firestore.FieldValue.serverTimestamp() in order to tell Firestore to use the current moment in time as the request reaches the server.
When storing timestamps, it is recommended you use the serverTimestamp
static method on the FieldValue class. When written to the database,
the Firebase servers will write a new timestamp based on their time,
rather than the clients. This helps resolve any data consistency
issues with different client timezones:
firestore().doc('users/ABC').update({
createdAt: firestore.FieldValue.serverTimestamp(),
});
Also read:
https://medium.com/firebase-developers/the-secrets-of-firestore-fieldvalue-servertimestamp-revealed-29dd7a38a82b

Ordering post with time and points (like reddit) firestore

I what to create a query for firebase firestore that gives me the "hottest" posts. I want a query like this to work with nodejs:
SELECT Title, LOG10(Likes + 1) * 86400 / .301029995663981 + UNIX_TIMESTAMP(Submitted) AS Hotness
FROM article
ORDER BY Hotness DESC
What is the best way of doing this with firestore?
Credit for this query: Reddit hotness score
One solution is to add a field in each post document with the value of the calculation.
Each time a post doc is updated, you would update this field through a Cloud Function (i.e. from the back-end). Since Cloud Functions code is executed with admin privileges, you can write a security rule that prevents the user directly updating this field (See the doc), and still have the field updated by the Cloud Functions.
To do the calculation, you need the nbr of likes, which you should have and the creation date.
For the creation date, just do do as follows when you create the doc:
....collection('posts').add({foo: 'bar', ..., createdOn: firebase.firestore.FieldValue.serverTimestamp()});
This way, your query is a very simple orderBy query, see the Firestore doc.

Server timestamp using firebase

I am working on a review/comment process and would like to be able to store each review/comment given by a user for another one in firebase, with each review/rating given at the same time being under the same timestamp. I was using the JS function new Date().getTime() initially, and this works fine, but to ensure that users can't tamper with the value (ie by changing the date on their computer) I would like to use firebase timestamp instead.
Now, I want the end product to be a map:
[chatStartTime] : {
review : stars,
time : chatStartTime
}
Which I then incorporate into a firebase document using transaction.set(). Now the issue is the ChatStartTime, which is supposed to represent this timestamp. I have the code:
var chatStartTime = firebase.firestore.FieldValue.serverTimestamp();
As an aside, I am also hoping to get:
var chatStartTimeDate = chatStartTime.toDate();
However chatStartTimeDate leads to an error – my understanding is that this is because chatStartTime is essentially "void" until it is added to a document; is there any way to get around this and use this function? Also, if I just use chatStartTime for both instances, I end up with a map on the database of the form:
[object Object]
review : 4.5
time :
.sv: "timestamp"
Where .sv is a string type. How can I solve this issue? I'd like the end result to look something like (for example)
1579194722735
review : 4.5
time : 1579194722735
The FieldValue.serverTimestamp() value is written on the server at time of write. So you can't get it before the write happens. However, you can get the writeTime from the response. This should give you what you're after. Alternately, you could read the document back out after you write it to fetch the timestamp (but that seems unnecessary).
myCollection
.doc('foo')
.create({ timestamp: FirebaseFirestore.FieldValue.serverTimestamp() })
.then(result => {
const serverTime: Date = result.writeTime.toDate();
});

How can I verify with the DB certain fields while using GraphQL?

I'm currently doing some research on how to implement GraphQL in my current project. There's something that concerns me... How do I verify with the database that the information that is being passed it's actually from that user? Both queries and mutations are grabbed from a single endpoint, which then the client is in charge of performing reads and writes to the DB respectively.
While I see how to validate by type (string, id, number, etc...) I don't see a hook or a moment in which I can verify that the possible Ids which are passed are in fact from the current user. E.g:
query {
hero {
name
}
droid(id: "2000") {
name
}
}
How can I check with the db, that the current id, 2000, belongs to the current user?
I'm currently using .NET Core MVC 2 (If that helps).
I would have done something like this using Entity Framework:
_database.Droids.Where(x => x.UserId == userId && x.id == id).FirstOrDefaultAsync();
If that Id doesn't correspond to that user, it would return an empty object. Same goes for an insert operation (Mutation in GraphQL).
Is there a hook in which I can verify the data? How would I do it?
Thanks!
I don't mind if there's an example in NodeJS or C#

Timestamps for messages

I'm using firebase's database to host a real time messaging web app. I've finished the basic implementation but now want to add timestamps for users to see when messages were sent.
To add a message to a chatroom I use firebase.push() with the value as the sent message. I guess I'll have to switch this to .update() with the value as an object with the fields message and time sent.
I'm trying to figure out how to populate this time sent. I've heard of firebase.database.ServerValue.TIMESTAMP but from what I can tell it's hard to change that into a date and time. I'm heavily considering a unix timestamp like this var unix = Math.round(+new Date()/1000); since this is easy to convert.
Does anybody with any experience have any tips for which direction I should take? I don't need the timestamp to be super precise, just the date, hour, and minute.
When you write firebase.database.ServerValue.TIMESTAMP to a node, the value becomes a UNIX timestamp. See the Firebase reference documentation for an example how to write this:
var sessionsRef = firebase.database().ref('sessions');
var mySessionRef = sessionsRef.push();
mySessionRef.update({ startedAt: firebase.database.ServerValue.TIMESTAMP });
When you read this value, you can convert it back into a Date object with:
sessionsRef.on('child_added', function(snapshot) {
var startedAt = new Date(snapshot.val().startedAt);
});

Categories

Resources