Open sebagnz opened 5 months ago
Some things to consider:
Transactions on web/mobile clients use optimistic concurrency to avoid locking data. This comes at the cost of having to retry transaction when data is changed from elsewhere, before the commit is done. Understanding what commit errors can be retried and which are permanent errors is a complexity that is abstracted away by using the update function closure. The client SDK handles retry, with backoff, responding differently according to the error code. By exposing a transaction object with begin/commit, the application developer will now have to take responsibility for this.
The transaction object (transaction.set) and the firestore modular functions (setDoc) are quite different. When reading/writing through modular functions, you can work offline and have your writes queued for when you go back online. The changes you make will be visible immediately, by reading through the cache.
Transactions on the other hand, only work when you are online and do not become visible until they are written to Firestore, and then retrieved again. The transaction read and write path does not go through the cache.
Are you running in a safe trusted environment with reliable internet connection? If so, the feature you describe might be better aligned for the Server SDK. Transactions is an area we want to improve, so understanding your use case better will be helpful.
Thanks for the detailed explanation @tom-andersen
I didn't know there were that many differences between transactions and modular operations. It there any place I can read more about this? I'd like to learn more about how this is intended to be used and how it works.
I understand that is not possible to add the begin/commit
transaction API because the update closure abstracts a lot of functionality from end users.
My end goal in this case was to build a full client side application as a POC for a product and only involve a server if the POC is successfull. That's the primary reason of why I choose firestore as my storage... because it gives me the possibility to delegate authentication and storage in a very straighforward way and without involving any server side code.
Answering to your question: Yes, I'm running in a safe trusted environment and I could use the server SDK, but that would be a next step in the product lifecycle.
I think that the example I provided shows a very common pattern for separating concerns in a web app. If adding the begin/commit
transaction is not possible, then do you think that this would be the way to go? Or do you know about any ressources that provide guidance on how to architect an app using firestore (JS SDK) transactions without having everything in the same file?
We have a page describing transactions and how they differ here: https://firebase.google.com/docs/firestore/transaction-data-contention
Here is some documentation cache provided by Web/Mobile SDKs: https://firebase.google.com/docs/firestore/manage-data/enable-offline
Note that the write guarantees of a transaction are much higher and therefore do not align with offline data. We cannot guarantee preconditions are still true when the client goes back online. Nor do we know whether the client will ever go online again.
I think your feature request is better implemented in the Server SDK that uses pessimistic concurrency controls. Please feel free to create an issue there as well, since customer feature requests help drive priority in development.
Operating System
N/A
Browser Version
N/A
Firebase SDK Version
N/A
Firebase SDK Product:
Firestore
Describe your project's tooling
N/A
Describe the problem
Feature request
Would it be possible to provide an API for begginning/commiting a transaction without having to perform all the transaction operantions within a single closure?
Also it would be extremely helpful to not have to use another set of functions to manipulate the data when using a transaction and when not. When inside a transaction, operations have to be done through the
transaction
object (transaction.set
) and when there is no transaction they are done through the firestore modular functions (setDoc
).Problem description
The fact that firebase only provides the
runTransaction()
api is very limiting for architecturing an app using different architectural patterns and abstracting functionality as the application scales.For instance
In the case of implementing a service/repository pattern, where the service handles all the business logic and the repositories encapsulates all the database queries, the issue is clearly visible when I need to start a transaction from the service and call multiple repositories involved in the operation.
Now I'm forced to:
transaction
object between the service and the repositories.transaction
object in each operation.setDoc
vstransaction.set
Code example
Steps and code to reproduce issue
N/A