我不了解 java/kotlin,但这是我在 Cloud Function 中的 TypeScript/JavaScript 中的做法。
const beerTapIndex: number = parseInt(req.params.beerTapIndex);
const firestore: FirebaseFirestore.Firestore = admin.firestore();
firestore
.runTransaction((transaction: FirebaseFirestore.Transaction) => {
const query: FirebaseFirestore.Query = firestore
.collection('beerOnTap')
.where('tapIndexOrder', '==', beerTapIndex)
.limit(1);
return transaction
.get(query)
.then((snapshot: FirebaseFirestore.QuerySnapshot) => {
const beerTapDoc: FirebaseFirestore.QueryDocumentSnapshot = snapshot.docs[0];
const beerTapData: FirebaseFirestore.DocumentData = beerTapDoc.data();
const beerTapRef: FirebaseFirestore.DocumentReference = firestore
.collection('beerOnTap')
.doc(beerTapDoc.id);
transaction.update(beerTapRef, {enabled: !beerTapData.enabled});
return beerTapData;
})
})
.then((beerTapData: FirebaseFirestore.DocumentData) => {
console.log('Transaction successfully committed!', beerTapData);
})
.catch((error: Error) => {
console.log('Transaction failed:', error);
});
计划 JavaScript 版本
const beerTapIndex = parseInt(req.params.beerTapIndex);
const firestore = admin.firestore();
firestore
.runTransaction((transaction) => {
const query = firestore
.collection('beerOnTap')
.where('tapIndexOrder', '==', beerTapIndex)
.limit(1);
return transaction
.get(query)
.then((snapshot) => {
const beerTapDoc = snapshot.docs[0];
const beerTapData = beerTapDoc.data();
const beerTapRef = firestore
.collection('beerOnTap')
.doc(beerTapDoc.id);
transaction.update(beerTapRef, {enabled: !beerTapData.enabled});
return beerTapData;
})
})
.then((beerTapData) => {
console.log('Transaction successfully committed!', beerTapData);
})
.catch((error) => {
console.log('Transaction failed:', error);
});
在这里找到我的答案:https://medium.com/@feloy/building-a-multi-player-board-game-with-firebase-firestore-functions-part-1-17527c5716c5
异步/等待版本
private async _tapPouringStart(req: express.Request, res: express.Response): Promise<void> {
const beerTapIndex: number = parseInt(req.params.beerTapIndex);
const firestore: FirebaseFirestore.Firestore = admin.firestore();
try {
await firestore.runTransaction(async (transaction: FirebaseFirestore.Transaction) => {
const query: FirebaseFirestore.Query = firestore
.collection('beerOnTap')
.where('tapIndexOrder', '==', beerTapIndex)
.limit(1);
const snapshot: FirebaseFirestore.QuerySnapshot = await transaction.get(query);
const beerTapDoc: FirebaseFirestore.QueryDocumentSnapshot = snapshot.docs[0];
const beerTapData: FirebaseFirestore.DocumentData = beerTapDoc.data();
const beerTapRef: FirebaseFirestore.DocumentReference = firestore
.collection('beerOnTap')
.doc(beerTapDoc.id);
transaction.update(beerTapRef, {enabled: !beerTapData.enabled});
const beerTapModel = new BeerTapModel({
...beerTapData,
tapId: beerTapDoc.id,
});
res.send(beerTapModel);
});
} catch (error) {
res.send(error);
}
}