我正在寻找一种方法来创建一个firestore事务,我从查询中找到一个文档,然后在事务中修改这个文档。
沿着这些方向做某事(kotlin):
firestore.runTransaction { transaction ->
val snapshot = transaction.get(db.collection("document")
.whereEqualTo("someField", null)
.orderBy("creationDate", ASCENDING)
.limit(1L))
val myObject = snapshot.toObject(MyObject::class.java)
myObject.someFiled = "123"
transaction.set(snapshot.reference, myObject)
}
这里的问题是.limit(1)
方法返回的查询不是DocumentReference,它是事务接受的唯一类型。因此我的问题是,如何在java / kotlin中实现这样的交易?
我在this blog post使用admin sdk:
看到了类似的内容 return trs.get(db.collection('rooms')
.where('full', '==', false)
.where('size', '==', size)
.limit(1));
答案 0 :(得分:0)
我不知道java / kotlin,但是我在云函数中的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);
});
异步/等待版
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);
}
}
答案 1 :(得分:0)
经过调查,您似乎无法在Kotlin / Java中执行此操作,因此不支持该功能。您将必须创建云功能并执行以下操作:
exports.executeTransaction = functions.https.onRequest(async (req, res) => {
const db = admin.firestore();
const query = db
.collection('collection')
.where('name', '==', 'name')
.limit(1);
db.runTransaction(transaction => {
return transaction
.get(query)
.then((querySnapshot) => {
const gameDocSnapshot = querySnapshot.docs[0];
const gameData = gameDocSnapshot.data();
transaction.update(gameDocSnapshot.ref, { name: 'change' });
return gameData;
})
})
.then((gameData) => {
res.send(gameData);
console.log('Transaction successfully committed!', gameData);
})
.catch((error) => {
res.send('Transaction failed:' + error);
console.log('Transaction failed:', error);
});
});