Firebase Firestore 在事务中添加新文档 - Transaction.add 不是一个函数



我假设可以做这样的事情:

transaction.add(collectionRef,{
uid: userId,
name: name,
fsTimestamp: firebase.firestore.Timestamp.now(),
});

但显然不是:

transaction.add 不是一个函数

上述消息显示在 chrome 控制台内。

我看到我们可以使用事务的set方法来事务性地添加新文档。 请参阅:https://firebase.google.com/docs/firestore/manage-data/transactions

问题是如果我使用set而不是 add(无论如何都不支持),文档的 id 应该由我手动创建,firestore 不会创建它。 请参阅: https://firebase.google.com/docs/firestore/manage-data/add-data

您是否看到没有自动为您生成 id 的 add 方法有什么缺点?

例如,考虑到包括性能在内的各种问题,是否有可能以某种方式优化 Firestore 本身生成的 id?

在使用 transaction.set 时,您使用哪个库/方法在 react-native 中创建文档 ID?

谢谢

如果你想生成一个唯一的 ID 供以后在事务中创建文档时使用,你所要做的就是使用不带参数的 CollectionReference.doc() 来生成一个 DocumentReference,你可以在以后的事务中设置()。

(你在答案中提出的是要做更多的工作才能达到同样的效果。

// Create a reference to a document that doesn't exist yet, it has a random id
const newDocRef = db.collection('coll').doc();
// Then, later in a transaction:
transaction.set(newDocRef, { ... });

经过更多的挖掘,我在 firestore 本身的源代码中找到了以下用于生成 id 的类/方法:

export class AutoId {
static newId(): string {
// Alphanumeric characters
const chars =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let autoId = '';
for (let i = 0; i < 20; i++) {
autoId += chars.charAt(Math.floor(Math.random() * chars.length));
}
assert(autoId.length === 20, 'Invalid auto ID: ' + autoId);
return autoId;
}
}

参见:https://github.com/firebase/firebase-js-sdk/blob/73a586c92afe3f39a844b2be86086fddb6877bb7/packages/firestore/src/util/misc.ts#L36

我提取了该方法(断言语句除外)并将其放在代码中的方法中。然后我使用了交易的设置方法,如下所示:

generateFirestoreId(){
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let autoId = '';
for (let i = 0; i < 20; i++) {
autoId += chars.charAt(Math.floor(Math.random() * chars.length));
}
//assert(autoId.length === 20, 'Invalid auto ID: ' + autoId);
return autoId;
}

然后

newDocRef = db.collection("PARENTCOLL").doc(PARENTDOCID).collection('SUBCOLL').doc(this.generateFirestoreId());
transaction.set(newDocRef,{
uid: userId,
name: name,
fsTimestamp: firebase.firestore.Timestamp.now(),
});

由于我对 id 生成使用与火库本身相同的算法,我感觉更好。

希望这对某人有所帮助/指导。

干杯。

根据 Doug Stevenson 的回答,这就是我如何让它与 @angular/fire 一起工作:

// Create a reference to a document and provide it a random id, e.g. by using uuidv4
const newDocRef = this.db.collection('coll').doc(uuidv4()).ref;
// In the transaction:
transaction.set(newDocRef, { ... });

完成 Stefan 的回答。对于那些使用Angularfire的用户,使用CollectionReference.doc()的5.2版本早期会导致错误"CollectionReference.doc()要求其第一个参数的类型为非空字符串"。

此解决方法对我有用:

const id = this.afs.createId();
const ref = this.afs.collection(this.collectionRef).doc(id);
transaction.set(ref, { ... });

信用:https://github.com/angular/angularfire/issues/1974#issuecomment-448449448

我想添加一个解决id问题的答案。无需生成自己的iddocumentReference在调用transaction.set()后更新,因此为了访问Firestore的id,您只需执行以下操作:

const docRef = collectionRef.doc();
const result = await transaction.set(docRef, input);
const id = docRef.id;

首先,firestore 事务对象有 4 个(获取、设置、更新、删除)方法,没有"add"方法。但是,可以改用"set"方法。

import { collection,doc,runTransaction } from "firebase/firestore";

另一方面,必须为"set"方法创建文档引用。

步骤:

1-) 集合方法创建一个集合引用对象。

const collectionRef = collection(FirebaseDb,"[colpath]");

2-)doc方法为指定的集合创建一个具有唯一随机 ID 的文档引用对象引用。

const documentRef = doc(collectionRef);

3-)添加操作可以用事务方法执行

try {
await runTransaction(FirebaseDb,async (transaction) => {

await transaction.set(documentRef, {
uid: userId,
name: name,
fsTimestamp: firebase.firestore.Timestamp.now(),
});

})
} catch (e) {
console.error("Error : ", e);
}

最新更新