Is there any TTL option on documents for Firebase Firestore . Where documents get auto deleted after that amount time
Update (2022-07-26): Firestore just added the option to set a time-to-live policy on collection groups. I'm still leaving the custom approach below, as those give you control over the expunge moment which (for now) isn't possible with the built-in feature.
The easiest way to build it yourself is by:
Adding a expirationTimestamp property to your documents.
Denying read of documents whose expiration has passed in your security rules.
match /collection/{document} {
allow read: if resource.data.expirationTimestamp > request.time.date();
}
Unfortunately this means that you won't be able to query the collection anymore. You'll need to access the individual documents.
Periodically run Cloud Functions code to delete expired documents.
Also see Doug's excellent blog post describing this process: How to schedule a Cloud Function to run in the future with Cloud Tasks (to build a Firestore document TTL).
Firestore TTL policies is now available in preview
https://cloud.google.com/firestore/docs/ttl
As of July 26th 2022, TTL Policies for Firestore were released as a preview feature (which means its not ready for production). Update Oct 2022: The TTL Policies feature has graduated from preview to General Availability, which means it should now be ready for production!
In order to use TTL Policies in Firestore, make sure that your documents have a field (of type Date & Time) to define the expiration date of that document (let's name the field expireAt for example).
And then follow the steps outlined in the documentation:
Go to the Cloud Firestore Time-to-live page in the Google Cloud Platform Console.
Go to the Time-to-live page.
Click Create Policy.
Enter a collection group name and the timestamp field name (expireAt in our example).
Click Create.
Related
I have a user-profile collection. Currently it is writable by only the user whose profile it is.
Now I want to record the count 'no of times the profile visited' let say profileVisitedCount. And, it also counts if a non-signedIn user visit the profile.
If I store the count in the documents of user-profile collection itself from firebase js client library, I will have to make it publicly writable.
Other option I am thinking is to have a cloud function. It will only increment the profileVisitedCount without need of making the the document publicly writable. But not sure if it is a correct approach, as the cloud function endpoint seems still vulnerable and can be called by bot.
Also, yes 'the profile visit count' kind of data should be recorded in analytics like GA but I need this count to use in one of the business logic like displaying top visited profiles.
So, any guidance on how the data should be structured? Thanks!
You could have another collection called, for example, profileVisitsCounters in which you store one document per user with a document Id corresponding to the user Id. In this user document, you maintain a dedicated profileVisitedCount field that you update with increment() each time a user reads the corresponding profile.
You assign full read and write access to this collection with allow read, write: if true;.
In your question, while mentioning the Cloud Function solution, you write that "the cloud function endpoint seems still vulnerable and can be called by bot". Be aware that in the case of an extra collection with full write access, as detailed above, it will also be the case: for example, someone who knows the collection name and user uid(s) could call the update() method of the JavaScript SDK or, even easier, an endpoint of the Cloud Firestore API.
If you want to avoid this risk you could use a callable Cloud Function to read the User Profiles, as you have mentioned. This Cloud Function will:
Fetch the User Profile data;
Increment the profileVisitedCount field (in the User Profile document);
Send back the User Profile data to the client.
You need to deny read access right to the user-profile collection, in order to force the users to "read" it through the Cloud Function.
This way you are sure that the profileVisitedCount fields are only incremented when there is a "real" User Profile read.
Note also that you could still keep the profileVisitsCounters collection if having two different collections brings some extra advantages for your business case. In this case, the Cloud Function would increment the counter in this collection, instead of incrementing it in the User Profile itself. You would restrict the access right of the profileVisitsCounters collection to read only since the Cloud Function bypasses the security rules. (allow read: if true; allow write: if false;).
Finally, note that it might be interesting to read this article, which, among others, details the pros and cons of querying Firebase databases with Cloud Functions.
I want to be sure that I can save data offline. How to synchronize data in Room with Firestore? When something inserted to Room Firestore must be updated as well.
Firestore already has a persistence layer included, you don't need Room at all. You can enable the offline support like this:
val settings = FirebaseFirestoreSettings.Builder()
.setPersistenceEnabled(true)
.build()
db.firestoreSettings = settings
Using Firestore for persistance has many benefits over Room (besides the saved effort and potential bugs). If you e.g. load all restaurants in a city, then go offline and then run a query on e.g. the best restaurants the query will still work and use the cached data even when the query was never run while being online.
You can also configure the cache size Firestore uses to meet your needs. Documents are cached in a LRU manner, so the documents which were not used for the longest time get removed from the cache first once it is full.
A best practice is to always use snapshot listeners. If you start a query in offline mode and the device gets back online, Firestore will automatically run the query again with the server and return the updated result to your UI.
Check out the docs and this video about Firestore offline mode for more details.
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
In Cosmos Db, I am using a document level Time to Live (TTL) and Cosmos does not appear to be expiring documents. Does this feature work in Cosmos Db using MongoDB API? If it does, what am I missing?
I am using Cosmos Db with the MongoDB API.
A "ttl" field is set in each document for my collection.
In Azure, Time to Live is set to "On (no default)" for my collection.
I am doing this without the emulator because the emulator defaults to the SQL API. In the emulator, I see "_ts" set and I do not see this field in Azure.
I can switch to collection level expiration by setting Time to Live to "On" and documents expire as expected. When I do this, my "ttl" field is ignored and the value I set for "second(s)" in Azure is followed. I still see my "ttl" field in the document.
Although I don't see a "_ts" field in my documents, an article about indexing mentions that it is a reserved property. This makes be think that it is set behind the scenes and it is not returned in queries.
https://learn.microsoft.com/en-us/azure/cosmos-db/mongodb-indexing
"_ts is a Cosmos DB-specific field and is not accessible from MongoDB clients. It is a reserved (system) property that contains the timestamp of the document's last modification."
Update:
I checked the MongoDB support page (https://learn.microsoft.com/en-us/azure/cosmos-db/mongodb-feature-support) and it indicates that collection level TTL is available and says nothing about document level.
Azure Cosmos DB supports a relative time-to-live (TTL) based on the timestamp of the document. TTL can be enabled for MongoDB API collections through the Azure portal.
Update:
My Azure Portal Preview Features now show this:
I got document level Time to Live working in Cosmos Db using MongoDb API. I had to ask help from Microsoft support to get this working. Response from Microsoft Big data team was following.
Before enabling Document level TTL feature , I would like to
clarify following about Document TTL feature details here.
The TTL feature is controlled by TTL properties at two levels -
Collection level and the Document level.
Right now per Document level TTL for MongoDB accounts are not
available by default. However, we can enable this feature for specific
customers and this feature is set at an account level.
TTL is at a document level but the feature is enabled at an account
level which means for all collections under the account, if there is a
document with a TTL set, it will take effect. For other collections,
if the TTL value is not set for each document, it would not be
affected.
You needs to have an index on the _ts field for this to work.
To summarize this : - This feature works at Cosmos DB account level.
We need to enable Document TTL feature in Cosmos DB backend on our
side.
Is there any TTL option on documents for Firebase Firestore . Where documents get auto deleted after that amount time
Update (2022-07-26): Firestore just added the option to set a time-to-live policy on collection groups. I'm still leaving the custom approach below, as those give you control over the expunge moment which (for now) isn't possible with the built-in feature.
The easiest way to build it yourself is by:
Adding a expirationTimestamp property to your documents.
Denying read of documents whose expiration has passed in your security rules.
match /collection/{document} {
allow read: if resource.data.expirationTimestamp > request.time.date();
}
Unfortunately this means that you won't be able to query the collection anymore. You'll need to access the individual documents.
Periodically run Cloud Functions code to delete expired documents.
Also see Doug's excellent blog post describing this process: How to schedule a Cloud Function to run in the future with Cloud Tasks (to build a Firestore document TTL).
Firestore TTL policies is now available in preview
https://cloud.google.com/firestore/docs/ttl
As of July 26th 2022, TTL Policies for Firestore were released as a preview feature (which means its not ready for production). Update Oct 2022: The TTL Policies feature has graduated from preview to General Availability, which means it should now be ready for production!
In order to use TTL Policies in Firestore, make sure that your documents have a field (of type Date & Time) to define the expiration date of that document (let's name the field expireAt for example).
And then follow the steps outlined in the documentation:
Go to the Cloud Firestore Time-to-live page in the Google Cloud Platform Console.
Go to the Time-to-live page.
Click Create Policy.
Enter a collection group name and the timestamp field name (expireAt in our example).
Click Create.