Cloud Firestore serving outdated data - firebase

In the last day, I have started having trouble with Cloud Firestore serving outdated data to my Flutter app running on android. I tried clearing the cache for the app, uninstalling/reinstalling with no success. Still Firestore kept serving the outdated data. Then I tried disabling persistence with the persistenceEnabled: false at startup. It stopped serving the outdated data, but now it doesn't return current data that should be returned! Any suggestions to check what might be going on?
Edit: I should mention that this is happening on a collectionGroup query for which the index has been built. I've checked the database rules, and there are not any denies or errors resulting from this query.

Turns out I changed one of my Collection group queries recently and needed to update the index. So if you have Cloud Firestore queries that are acting erratic like mine was, check out your logcat or console log for an error like this:
Unhandled Exception: [cloud_firestore/failed-precondition] Operation was rejected because the system is not in a state required for the operation's execution. If performing a query, ensure it has been indexed via the Firebase console.
Firestore is supposed to provide a URL to build the appropriate index, but in my case the URL did not appear so I had to add it manually.

Related

Extremely high READ hits on website using Firebase Firestore

I have more than 52k hits on my small project which is using NextJS with Firebase 9.
I don't know what the problem is because the data I am using is very limited and I have only two snapshot listener and one Authentication feature. But somehow in just two days Firestore quota has exceeded and there are more than 52k READ hits.
I don't know why that happened because there are no memory leaks and I am also closing the API listeners which come attached with Firebase.
I am providing github link in case anyone wants to take a look https://github.com/jainChetan81/Todo-List
Attached screenshot of Firebase console:
Use of the Firebase console will incur reads. If you leave the console open on a collection or document with busy write activity then the Firebase console will automatically read the changes that update the console's display. Most of the time this is the reason for unexpected high reads. You can go through this answer. Also, currently there are no tools to trace the reads in Firestore. So to limit the Firestore database reads you have to configure security rules.
So, I would suggest you check your Firestore rules. And if not, it is better to contact Firebase Support as this kind of issue needs visibility into your project and they will have access to it.
I am having the same problem as you with my React app. The solution is to use the useEffect hook and call the function that requests for firestore collection;
useEffect(()=> {
getPosts();
}, []);

Getting firestore usage stats from firebase client libraries

I am trying to identify the reason for an abnormally high firestore read count in my android and web app.
If there was a way to profile firestore, I could get an idea of which collection, or which user is causing this high read count, but currently there is no way to profile firestore.
I added a log entry to my android and web apps to log the read count to a remote server, so I can troubleshoot the issue. But this log doesn't match the actual read count I see in the firestore console, so it looks like I have missed to log some places where firestore is queried.
The reason why firestore hasn't provided a way to profile firestore is because it is technically difficult for them to do it with the high load, as I read somewhere. But, it shouldn't be hard to track the usage at client library level.
Does anyone know a way to get the usage statistics out of the firestore client library? Or any other way to troubleshoot this issue?
There is currently no profiler. Please contact Firebase support and file a feature request to vote for this. Also, they might be able to help you understand the traffic.

Firestore Rules > Determine which collection / rule is failing

Is there any way to see the specific collection / rule that is failing in Firestore? I've looked in firestore-debug.log (running on localhost) as well as in the Firebase UI. Firestore logs the error to the console, but does not include the information I need to debug the permissions:
Firebase intentionally does not disclose information about what rule is failing, as it would give malicious users information you don't want them to have.
The best information is typically available in the emulator in the Firebase console, which tells you what specific rule has failed.
Error messages delivered to the client SDK will never show the root cause of the rejection, as that would reveal something about the security measure to a potential attacker.
If you want to test and debug your security rules locally before you deploy, you can use the Firebase emulator suite to get detailed information about how your rules are working with client code that would make queries against them.
https://firebase.google.com/docs/firestore/security/test-rules-emulator
https://firebase.google.com/docs/rules/emulator-setup

How to figure out if firestore security rule failed when client comes back online and pending write completes?

In my Android app I am writing data to firestore which is being validated with the help of security rules. Since writes work offline too, my (invalid) write task will return success if device is offline. But when the device comes online, the security rule will block the write and the data will disappear from the client. Is there a way for me to know that the write failed? Is it possible for a cloud function to be triggered if security rule fails so that I can inform the user that their write failed after going back online?
When you say "my (invalid) write task will return success if device is offline", this is not exactly how it works. When you write a document to Firestore the SDK will only confirm the write if the app is online and the server confirms that it's written. When you perform a write, the API is going to give you some sort of handle into that operation (Android Task, JavaScript promise) will be completed or resolved when that write actually finishes.
If you are offline, you'll never know for sure if the write was going to work, but the written document will still show up in queries. If you want to know if that document finally finished its write, you'll have to request metadata for that document, and check if that document has an outstanding pending write. For example, on Android, use hasPendingWrites() to find out if the document you have in hand was written.
The SDK doesn't provide you with a way of knowing when your documents sync after it's cold booted. But you can take matters into your own hands by remembering all the paths of the documents that are important to track, persist them locally, then load those paths on cold boot to check for success. You'd add listeners to those documents and check:
If the document doesn't exist, that means the write was rejected before you attached the listener.
If the document exists and hasPendingWrites(), that means the sync is still waiting to happen.
If the document exists without pending writes, it got synchronized successfully.
This strategy only works for adding new documents. For updating documents it's more difficult because a document without pending write may just be an old version of the document before the update sync failed. So you'd need to put some other field in the update that indicates if the update succeeded.

Firestore offline batch delete

I am new to firebase and firestore and would like to know if the behavior I found is a bug or by design.
I am using angularfire2 in my ionic project where the user will be offline most of the timeā€¦ so offline support is a big deal.
The problem: snapshotChanges is not called in a offline batch delete of subcolletion.
I have something like this in firestore /users/{userId}/projects/{projectId}/points/{pointId}
When a user inserts a new project or point a use set and the object is written fine, my lists are updated with the new instance and it works great thanks to snapshotChanges. When the user removes a project is the problem..
I execute a batch delete in the points of a project and after that I delete the project itself. This works fine online, but not offline. My lists are not being updated even though the operation completes with success. I could reproduce it multiple times, but only if the app is offline all the time ( the inserts and deletes are only local)
am I missing something?
The documentation states here:
Batched writes have fewer failure cases than transactions and use
simpler code. They are not affected by contention issues, because they
don't depend on consistently reading any documents. Batched writes
execute even when the user's device is offline.
This "Batched writes execute even when the user's device is offline" this makes me understand that the events of removal should be propagated to snapshotChanges.

Resources