如何在需要找到目标文档的地方创建Firestore交易 [英] How to create firestore transaction where target document needs to be found

查看:33
本文介绍了如何在需要找到目标文档的地方创建Firestore交易的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种创建Firestore事务的方法,该方法是从查询中找到文档,然后在事务中修改此文档.

I am looking for a way to create a firestore transaction where i find a document from a query and then modify this document in a transaction.

类似的东西(科特琳):

Something along those lines (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中实现这种交易?

The problem here is that the query returned by the .limit(1) method is not a DocumentReference, which is the only type the transaction accepts. Therefore my question is, how can such a transaction be achieved in java/kotlin?

我在

I have seen something similar in this blog post using the admin sdk:

  return trs.get(db.collection('rooms')
    .where('full', '==', false)
    .where('size', '==', size)
    .limit(1));

推荐答案

我不了解java/kotlin,但这是我在Cloud Function中的TypeScript/JavaScript中实现的方法.

I don't know about java/kotlin but here is how I did it in TypeScript/JavaScript in a Cloud Function.

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版本

Plan JavaScript Version

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

Found my answer here: 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);
    }
}

这篇关于如何在需要找到目标文档的地方创建Firestore交易的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆