简体   繁体   中英

Multiple document reads in node js Firestore transaction

I want to perform a transaction that requires updating two documents using the previous values of those documents.

For the sake of the question, I'm trying to transfer 100 tokens from one app user to another. This operation must be atomic to keep the data integrity of my DB, so on the server side I though to use admin.firestore().runTransaction .

As I understand runTransaction needs to perform all reads before performing writes, so how do I read both user's balance before updating the data?

This is what I have so far:

db = admin.firestore();
const user1Ref = db.collection('users').doc(user1Id);
const user2Ref = db.collection('users').doc(user2Id);
transaction = db.runTransaction(t => {
    return t.get(user1Ref).then(user1Snap => {
        const user1Balance = user1Snap.data().balance;
        // Somehow get the second user's balance (user2Balance)
        t.update(user1Ref , {balance: user1Balance - 100});
        t.update(user2Ref , {balance: user2Balance + 100});
        return Promise.resolve('Transferred 100 tokens from ' + user1Id + ' to ' + user2Id);
    });
}).then(result => {
    console.log('Transaction success', result);
});

You can use Promise.all() to generate a single promise that resolves when all promises in the array passed to it have resolved. Use that promise to continue work after all your document reads are complete - it will contain all the results. The general form of your code should be like this:

const p1 = t.get(user1Ref)
const p2 = t.get(user2Ref)
const pAll = Promise.all([p1, p2])
pAll.then(results => {
    snap1 = results[0]
    snap2 = results[1]
    // work with snap1 and snap2 here, make updates to refs...
})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM