Robert Lemiesz
Robert Lemiesz

Reputation: 1156

Concurrently updating an array in firebase

.runTransaction(async transaction => {
    const newContractUid = uuid();
    const newContractRef = firestore
        .collection(COLLECTION_CONTRACTS)
        .doc(newContractUid);
    const creatorRef = firestore.collection(COLLECTION_USERS).doc(creatorId);
    const recipientRef = firestore
        .collection(COLLECTION_USERS)
        .doc(recipientId);
    const [creator, recipient, newContractDoc] = [
        await transaction.get(creatorRef),
        await transaction.get(recipientRef),
        await transaction.get(newContractRef)
    ];
    if (newContractDoc.exists) {
        console.warn("Attempted to create contract with already taked UUID");
        return Promise.reject(
            "Attempted to create contract with already taken UUID"
        );
    }
    contractData.creationDate = Date.now().toString();

    transaction.set(newContractRef, contractData);
    // Update recipient and creator with contract relations
    transaction.update(creatorRef, {
        contracts: _.concat(creator.data().contracts, newContractUid)
    });
    transaction.update(recipientRef, {
        contracts: _.concat(recipient.data().contracts, newContractUid)
    });
})

I have this code that creates a new contract in my firestore. It then relates this contract to two users a creator and recipient.

However I am worried about this line of code:

transaction.update(creatorRef, {
    contracts: _.concat(creator.data().contracts, newContractUid)
});

Is it possible for another user to write to the creator.data() field while the transaction is happening and invalidate my data here. Or do I have a write lock for the duration of the transaction?

EDIT:

Hmm i see this in the firebase docs

For example, if a transaction reads documents and another client modifies any of those documents, Cloud Firestore retries the transaction. This feature ensures that the transaction runs on up-to-date and consistent data.

I think this means I am safe in this case but I am not sure

Upvotes: 1

Views: 538

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 598857

A Firestore transaction protects against concurrent writes. If it detects a conflicting write, it retries the transaction, so your transaction handler might get invoked more than once for a single write operation.

Upvotes: 2

Related Questions