Repository navigation
Replies: 7 comments 20 replies
|
This has the feel of an issue report but you opened a discussion and avoided populating all the useful information I'd need to offer help unfortunately Make sure you are on up to date versions, first. If you're not, do that. I'll assume you've done that now. I do not believe you are missing anything, but before going to the trouble of a reproduction here I'd check upstream and trying to reproduce there with their quickstart, as I do not think it's possible for the code in this module to be double-writing |
|
Getting later here, but I know this bug very well. It's not from this library, it's from Firestore itself. You can reproduce this bug in every SDK available. Here is a simulator using the js-sdk: https://codesandbox.io/s/dreamy-shadow-isgwl . There is a big discussion on slack too, between me and some other guys, but it is too old to access: https://firebase-community.slack.com/archives/C7CQWAH7F/p1608061793176100. In January 2021 I open up a support ticket with the Firebase support team and they successfully reproduce the "bug" but they didn't have a foresight to solve the problem. That was the final response:
In my case, the application don't multiple devices writing on the same "field" so I made a workaround that was increment locally and update the field. |
|
I came to a similar conclusion and workaround, looks like Fieldvalue.increment is not really usable unless you are certain that you aren't writing to the same document in quick succession. Using the test above I could only recreate the issue when writes were performed < approx 300ms apart. The Firestore Best practices do state that documents shouldn't be written to more than once per second. I also couldn't use transactions because my app needs to work in offline mode (the main reason we use Firestore at all) |
|
Is there any open issue with Google about this? I have the same problem on a big scale system right now, it's driving me crazy. Switching from |
|
It kinda pisses me off that Google/Firebase are hiding all these limitations from us, and I have to find it in a discussion thread on GitHub; and we don't even use React! I WANT to know these things before working on my architecture. Now we need to rework a lot of code, that uses FieldValue.increment, because of this. EDIT: EDIT2: They've since removed the 1 write per second recommendation btw: https://stackoverflow.com/a/74455395/536485 |
|
Hey folks, one somewhat low cost mitigation would be to have an integrityCount using FieldValue.increment running inside a batch together with whatever operation you are running it in, if the FieldValue.increment runs twice inside the batch it is most likely due to batch being retried due to failure by the client to acknoledge the write from the server when they were merging the data. In our situation we noticed that that all FieldValue.increment would duplicate together inside the batch, so we have a cloud function which checks this integrityCount and ammend the data when duplication is detected. |
|
Hey guys I found a better solution for it: If the client never receives the server's ack for a commit (flaky network, app backgrounded), the Firestore SDK can resend the whole batch. Plain set/update writes are idempotent, so a resend does no harm. But FieldValue.increment(x) gets applied twice, so balances and counters drift. Fix: add an idempotency marker to the same batch and let security rules refuse a second copy.
Do this in one shared place every batch passes through, not screen by screen.
On a resend (automatic retry from the SDK), the marker already exists, so the set counts as an update and is denied. Batches are atomic, so the whole resent batch is rejected, increments included. The user sees nothing.
Testing: commit a batch, then commit an identical copy (same saveId, same amounts) against the emulator with the real rules on. The first commit succeeds, the second fails with PERMISSION_DENIED, and the counters equal the values after the first commit. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Over the last couple of days I have noticed some concerning behaviour with Fieldvalue.increment.
Every so often set/update operations get duplicated, and if that operation has an increment in it then it messes up my data. I am 100% certain that I am not calling the operation twice, I have tested extensively to confirm this.
From inspecting the firebase logs I can see when it happens that duplicate writes are happening within single digit milliseconds of each other. It happens randomly so it is very hard to reproduce.
This is happening in offline mode as well as online, both on the emulators and using remote firebase services. I am the only one running the client so it is not a case of multiple people incrementing.
I am not writing to the documents more than once a second.
Am I misunderstanding something about how firestore works internally? What happens under the hood that would cause a write to be duplicated?
I'm at my wits end here as this is affecting users in production and it's looking like I am going to have to refactor to remove any usage of increment and do it manually, which is going to end up costing more.
I will create a reproducible demo if needed, but first I wanted to ask whether I am missing something crucial in what I expect firestore to be able to do.
All reactions