In Python, we can perform queries on collections within a transaction using the following code snippet:
def write_upload_success(filename: str, uid: str, doc_id: str) -> DocumentReference:
db = firestore.client()
transaction = db.transaction()
@firestore.transactional
def transaction_operation(transaction) -> str:
# Query to check if the filename exists
notes_ref = db.collection('users').document(uid).collection('notes')
# Find the largest order number in the existing notes
order_query = notes_ref.order_by('order', direction=firestore.Query.DESCENDING).limit(1).get(transaction=transaction)
max_order_note = None
for note in order_query:
max_order_note = note
break
order = max_order_note.get('order') + 1 if max_order_note else 1
note_ref = notes_ref.document(doc_id)
#
# ...
#
return note_ref
return transaction_operation(transaction)
It appears that Python allows querying collections within a transaction using:
notes_ref.order_by('order', direction=firestore.Query.DESCENDING).limit(1).get(transaction=transaction)
However, I haven't been able to find an equivalent approach in Swift. Is it not possible to perform collection queries within a transaction in Swift?
Thanks.
p/s Almost all AIs will wrongly suggest using transaction.getDocuments
in Swift, which this function doesn't exist.
It's not possible.
The issue is that the python SDK assumes that it's running on a server environment with a stable and performant internet connection, so it allows for complex queries to be run on a transactional basis using pessimistic locking. The same is true for other SDKs in server environments, such as nodejs and java. There is no swift SDK for server environments.
All of the web and mobile SDKs (include the iOS swift SDK) assume the opposite - they are expected to run on devices without a fast or stable connection. So they don't let you potential cause problems by executing complex queries in a transaction. Transactions on those platforms use optimistic locking, which is not really compatible with complex transactional queries.
See: