Firestore Offline: Make sure a specific Document is always cached - firebase

Lets say I have a workout app, where every workout is one DocumentSnapshot. I want to have a donwload button, that downloads a workout/document.
I'm already using firestore's offline capabilities, but I need to ensure, that when I have downloaded this document, it is always available when opening the app without a connection.
So is it possible to ensure, that a specific document is always being cached in the local firestore cache?
I could also just persist the data of the DocumentSnapshot, the problem with this is, I can't update the Document and have the changes being synchronized with the "online" database when reconnecting with the wifi.
Is there any good way to achieve this?

So is it possible to ensure, that a specific document is always being cached in the local firestore cache?
It's not possible to ensure 100% of the time. The local cache is fully managed by the Firestore SDK. You don't have control over how it chooses to evict data from the cache. Any given cached document might be removed to make room for other documents in the future, if the cache becomes full.
Also, the cached document will not stay in sync with whatever is on the server, unless you write code to periodically query for (or listen for changes) in that document.
The functionality you're describing is best implemented with application code (probably with its own persistence layer) that specifically meets the needs of your app. The Firestore SDK won't do it for you.

Related

How can I use local cache and only update changed documents using Firestore?

I'm working on a calendar app and I'm currently fetching the data from firestore to populate the calendar. Eventually, there will be a lot of data to be fetched and I'm trying to understand the caching system of Firestore but can't get behind it.
What I ideally want to achieve:
Always use cached data and only update those documents, which are new, edited or deleted.
How would I achieve that?
If you want to force the SDK to read from the cache, you can specify source options when calling get().
If you find yourself doing this everywhere though, it might make sense to consider using another database than Firestore as that is primarily an online, cloud-hosted database that continues to work while you're temporary offline.

Forcing an "Offline" Mode in Firestore

We are building an app for our teams out in the field that they collect their daily information using Firebase. However one of our concerns is poor connectivity. We are looking to build an Online/Offline button they can click to essentially work offline for when things slow down. We've built a workflow in which we query all the relevant information from Firestore.
I wanted to know if there was a way to tell Firestore to work directly on the cache only and not try to hit the servers directly. I don't want Firestore attempting to make server calls until they enable online again.
You shouldn't need to do this. If you use realtime listeners, they will already first return the data from the local cache, and only then reach out to the server to check for updates.
If you are performing one-time reads, the SDK will by default try to reach the server first (since it has only one chance to give you a value). If you want it to only check the local cache, you can pass an argument to the get call to do so.
You can also disable the network completely, in which case the client will never call on the network and only serve from the local cache. I recommend reading about that and more in the documentation on using Firestore offline.

Does Firestore read all documents on page load even if they havent changed?

I am developing a chrome extension for the new tab page and I am trying to find the right DB for the project. The only question that is keeping me from using Firebase Firestore is to know how the DB handles reads.
Basically, every time the user opens a new tab page I will need to fetch around 3000 (very small) documents (hopefully from cache). My issue is that since opening a new tab page is done so frequently I will be charged an absurd amount of reads because firestore is always reading 3K documents.
My question is, is Firestore smart enough to tell that in the DB data has not changed and the client should only read from the cache?
I read all about offline persistence but this question is still lingering!
Thank you for any help!
When you start a listener you read first from the cache and then from the server. The cache persistance here explains how it behaves but considering only that the listener is in the listening mode. Even then after a 30 in offline you would be charged for a full read.
I would recommend you to read this. To manage your cache on your own to awoid to much reads as you are reading a large amount of data.

how to delete specific firestore document in Source.CACHE?

I can specify the source If I want to get data from firestore, either default, from server or from cache like this:
query.get(Source.CACHE)
say I normally get 50 documents if using the code above.now I want to delete one specific document from that query in cache, so I want to get only 49 documents.
how to do that ? is it possible ?
You don't have direct control over the status of the internal cache maintained by the Firebase SDKs. You can't delete or invalidate specific items.
The cache is completely managed by the SDK. The SDK determines when documents should be added or removed, based on whether or not they are in sync with the server.
You can use the SDK to delete a document, which will remove it from cached results. But that delete will eventually get synchronized with the server, and that's a permanent change.
If you have steps that show that the internal cache is somehow buggy or inconsistent with the contents of the server, then file a bug report with Firebase support that shows now to reproduce the issue.
I want to delete one specific document from that query in cache, so I want to get only 49 documents.
There is no way you can specify that in a delete() operation. If you want to get that behavior, your device should be offline. In that way, Firestore will delete the record from the local cache. But please note, that once you regain the connection, your record will also be deleted from Firebase servers. While online, there is no way you can have a deleted document in the cache and not from Firebase servers.

how to synchronize Room data with Cloud Firestore?

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.

Resources