如何在事务中创建新的 Firestore 文档

How do you create a new Firestore document within a transaction

我正在尝试记录对一组客户记录的更改。为了保持万无一失,日志记录显然应该在 Firestore 事务中创建。我使用 transaction.set 应用客户文档更改没有问题,但每次此类更改都需要在我的 transactionLogs 集合中创建一个新文档。在这里,事情变得严重错误日志文档由时间戳字段标识,当我 运行 以下代码时: ...

import { initializeApp } from 'firebase/app';
import {
    getFirestore, collection, query, getDoc,
    getDocs, where, orderBy, addDoc, doc, updateDoc, deleteDoc, runTransaction
} from 'firebase/firestore';

var firebaseApp = initializeApp(firebaseConfig);
var db = getFirestore(firebaseApp);

// code to read and validate update to customer documents and to call the following asynch function

function performCustomerUpdate(parameters) {

await runTransaction(db, async (transaction) => {

 // update Customer document and build a transactionLog object

 const newLogRef = collection(db, 'transactionLogs', transactionLog.timeStamp);
 await transaction.set(newLogRef, transactionLog);

});
}

... transaction.set 指令无法表达类似 "Invalid collection reference. Collection references must have an odd number of segments, but transactionsLogs/1645451217221 has 2." 的内容 在这个特定实例中,1645451217221 本来就是 ​​transactionLog.timesStamp.

的值

有人对这里发生的事情以及如何修复错误有任何建议吗?我的理解是,如果提供的引用不存在,transaction.set 将创建一个新记录,所以我应该在正确的行上。但为什么 Firestore 认为我想在一个名为 transactionsLogs/1645451217221 的集合中创建它?如何获取它,为名为 'transactionsLogs'?

的集合中由字符串“1645451217221”标识的文档创建引用

如果您要指定文档 ID(而不是使用 auto-generated ID),那么您必须使用 doc() 而不是 collection() 来创建 DocumentReference

const newLogRef = doc(db, 'transactionLogs', transactionLog.timeStamp);

collection() 函数用于创建 CollectionReference.

同时结帐:


My understanding is that transaction.set will create a new record if the supplied reference doesn't exist

如果文档存在,它将覆盖现有文档。

关于如何在事务中添加记录这一更广泛的问题,答案是您将使用与在外部 事务中使用的代码几乎相同的代码.

因此,在事务之外,您将使用以下 Web 版本 9 代码创建一个新文档,其中包含 数据项 作为其标识符:

        const myDocRef = doc(db, "myCollection", myDocId);
        await setDoc(myDocRef, myDocData);

在事务中,您使用完全相同的模式,唯一的例外是 setDoc()transaction.set() 替换,并且整个操作(很明显)被runTransaction(db, async (transaction) => {指令包围:

    await runTransaction(db, async (transaction) => {

        const myDocRef = doc(db, "myCollection", myDocId);
        await transaction.set(myDocRef, myDocData);

    }).catch((error) => {
        alert(`Oops - transaction failed - error is : ${error}`);
    });

同样,用于创建具有 automatically-generated id 的文档的模式:

        const myCollectionRef = collection(db, "myCollection");
        const myDocRef = doc(myCollectionRef)
        await setDoc(myDocRef, myDocData);

在交易中被替换为

        const myCollectionRef = collection(db, "myCollection");
        const myDocRef = doc(myCollectionRef)
        await transaction.set(myDocRef, myDocData);

请注意,如果您发现需要查找分配给您的 automatically-generated id 的值,可以使用 myDocRef.id