Cloud Functions for Firebase: get actual timestamp of database - firebase

I need to get the actual timestamp of the firebase database servers instead of the placeholder firebase.database.ServerValue.TIMESTAMP.
In order to avoid an XY problem, I will provide my two use cases:
a) I have created my own reset password system using cloud functions and JWT. A user requests to reset their password. I sign an object containing their username and the current timestamp(currently using Date.now()) and send it embedded to a link to their email. When they open the link, I need to verify the JWT and also compare it to a timestamp stored under their uid in firebase database. I also update the timestamp in the database so next time they try to use the same token, it will show up as expired(even if the 1 hour expiration I have set for the token has not passed). Is using Date.now() here enough? How can I pass the current firebase time to jwt.sign().
b) I need to store a negative version of the creationTimestamp of all posts in the database for sorting purposes. -firebase.database.ServerValue.TIMESTAMP does not work. What is the correct way to do that?

Google goes through great trouble to make sure all of their servers have times that are as closely synchronized as possible. So, if you're running code in Cloud Functions, which ends up on a Google server, and you want to know the time on another Google server (like your Realtime Database), just use Date.now(). There's no need to use the special database token for timestamp when running in Cloud Functions.
That timestamp token is intended to be useful when code is running on client devices whose clocks may not be very well synchronized.

Related

How to save user data in db, without logging in?

I am working on a simple app that allows users to search for something using an API and save it to view later.
However, I don't want to integrate authentication in the app. I can, but would rather not as a UX decision. Do you know of a way to generate a device token, that is unique to every device and can be used to store which assets a device has saved in the db?
I am thinking of expo push tokens as a possible solution, but that would require users to accept push notifications - so what happens if a user says no?
Sounds like you could just use react-native-uid to generate a unique id for your device and then store it in AsyncStorage and fetch it from there going forward.
For more inspiration, or perhaps just a more canonical way to do this... read up on suggestions surroundings the recently deprecated constant for installationId here:
https://docs.expo.dev/versions/latest/sdk/constants
I haven't used this before but if you're looking for something bullet proof then this is probably your goal of getting the same concept.
Firebase Anonymous Authentication might be ideal to use in this case. This can be used to create a user in Firebase auth without any credentials and can be useful especially when you are using either of Firebase's databases since you can use security rules with user's UIDs.
However, once the user logs out of the account by any means including but not limited to using sign out option in your app, clearing app data or uninstalling the app, the same account with that UID cannot be recovered. I looked up for AsyncStorage and apparently that gets cleared to if the app is deleted.

I'd like to set a value on Firebase database to True just for a certain amount of time

I can't figure out how to change a value of Firebase database and then change it back after a certain amount of time(30 min), doing everything on the server side and not by the actual device date.
I'm assuming i need Firebase functions.
In case i can't do it, is there any other way keeping Firebase as main Database?
I don't really need any code but just the logic behind it.
I would question your data model. Instead of using a boolean, you may want to consider using a timestamp.
For example, if your data model is currently something along the lines of:
Permissions
- user_id
- is_allowed (boolean)
You may want to use this instead:
Permissions
- user_id
- allow_until (timestamp)
You application code can then just check if the current time is earlier than the allow_until timestamp.
There is no logic in the Firebase Realtime Database to automatically change a value after a certain amount of time. You'll typically run such code in Cloud Functions, or in the apps in your client devices.
In both cases you can keep using the Firebase Realtime Database, as you'll just be interacting with that. From Cloud Functions you'll do that through the Admin SDK.
It's a few steps:
Create a Cloud Function that queries the database to find expired items, and changes the value on them. This code uses the Admin SDK for Node.js, but is very similar to what you'd otherwise run in a web client.
Tie that Cloud Function to a cron job that runs every minute or so (depending on how accurate you want the time-out to be). For some options, see Cloud Functions for Firebase trigger on time?
I recommend you also check out these similar questions:
Delete firebase data older than 2 hours
How to delete firebase data after "n" days (doing the same from an Android client)
How to purge old content in firebase realtime database

Is it good idea to store sensitive info in firebase?

In my Android application I have an idea to store in database some serial key. If user enters correct key he gets full version of application and the key is disabled on the server to avoid multiply usage of the same key, otherwise he can buy app in Google Play without a key.
For this I thought to use Firebase Database but after read this I have some doubts
Firebase Realtime Database
Store and sync data with our NoSQL cloud database. Data is synced across all clients in realtime, and remains available when your app goes offline.
Does it mean that firebase will duplicate the table with all available keys to all application users and some smart user can read the list from this copy at his phone?
Not all data is automatically duplicated to all clients. Only data that the client subscribes to is received by that client.
You can control what data each client can see through Firebase's server-side security rules. For example, you'll typically want to ensure that each user can only read their own data.
It probably isn't a good idea to store super-sensitive data like social security numbers or credit card numbers, but if you see https://firebase.google.com/docs/database/security/ you can see, that you can control access to data, & use validation, especially since you can regenerate the keys if they become compromised, it wouldn't be the worst option. If you look at https://firebase.google.com/docs/database/security/user-security you can see, that it's possible to write an app that uses it like google drive with a smartphone-based client.
Personally the answer would no. You may want to think about Google Play Subscriptions and In-App Purchases.
If you really have to then:
Create a key as a user buys the upgrade (server-side).
Store the device id/account id (hashed) and timestamp with the key.
Credit card details and expiry dates should be combined into one hash.
Just encrypt everything.
It's better to have a banned list than a list of approved key. Eventually you have to create more keys and it's easier just to maintain a list of banned keys.

Firebase auto check time sending data to server? Or i must create variable Time?

I want create app with Realtime. When i send data to sever, but my internet is slow. Same time, other users send data and it go to server first. Firebase will put my data first or other users first?
There are two ways to handle time with Firebase and which one you'll want to use depends on your use-case. If you want to "check who pressed a key on their device first", you'll want to use Firebase's push() method to generate keys. If on the other hand you want to detect who's data reached the database first, you'll want to use ServerValue.TIMESTAMP.
When a device/browser connects to the Firebase Realtime database, it detects the time offset between the client and the server. It then uses this value to estimate the server timestamp it uses to generate client-side push() IDs. So these provide a reasonable (but not secure, they can be faked by the client) way to estimate when an event happened according to the user's device.
When you use ServerValue.TIMESTAMP in your code, the client initially uses the same time offset to estimate the server-side timestamp. Then it sends the data to the server, which corrects the timestamp if needed. so with this approach you're guaranteed that the timestamp is exactly when the data was written into the database on the server.

Firebase REST streaming for multiple users

I have a server that needs to receive real time updates from Firebase, for multiple users, where each user grants Oauth access to his Firebase data to my app.
My server is implemented using Firebase REST Streaming, based on Server Sent Events.
I need to know if there is a way to multiplex Firebase data pertaining to multiple users on a single stream.
I would like to be able to set up the stream with Oauth tokens pertaining to multiple users, and to subsequently receive real time updates pertaining to the multiple users on the same stream.
Otherwise, it seems that I need to maintain a separate stream per Oauth token, which seems to be non-scalable.
I think Twitter have a Site Streams feature like what I am looking for in their API, implemented via an envelope that indicates the user the message is targetted to.
Does Firebase support anything similar?
A single Firebase REST call will only monitor a single node. E.g.
curl 'https://samplechat.firebaseio-demo.com/users/jack/name.json'
You can control what data is returned from under that node with the orderBy, startAt,endAtandlimitTo...` parameters. E.g.
curl 'https://samplechat.firebaseio-demo.com/users/.json?orderBy="name"&startAt="Jack"'
There is no way to have a single REST request return data from different nodes/nodesets. So unless you find a way to gather all data you want to return under single node, where it can be returned by a single set of query parameters (orderBy, etc), you will have to execute multiple REST requests to get your data.
Note that the SDKs that Firebase provides internally use a web-socket protocol, so are not impacted by this limitation. If an SDK is available for your server-side language (e.g. node.js, Java), you could solve it by using that one.

Resources