firebase firestore在事务内添加新文档-transaction.add不是函数

时间:2019-04-14 10:06:45

标签: firebase react-native transactions google-cloud-firestore

我以为可以做类似的事情:

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?

谢谢

4 个答案:

答案 0 :(得分:1)

如果要生成唯一的ID供以后在事务中创建文档时使用,您要做的就是使用CollectionReference.doc()(不带参数)生成DocumentReference,稍后可以在set()中使用它。交易。

(您在答案中提出的建议是,为达到相同的效果需要做更多的工作。)

// Create a reference to a document that doesn't exist yet, it has a random id
const newDocRef = db.collectionRef('coll').doc();

// Then, later in a transaction:
transaction.set(newDocRef, { ... });

答案 1 :(得分:0)

经过进一步的挖掘,我在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

我提取了方法(断言语句除外),并将其放入代码中的方法内。然后,我使用了事务的set方法,如下所示:

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(),
                        });

由于我使用与Firestore本身相同的算法来生成ID,所以感觉更好。

希望这可以帮助/指导某人。

干杯。

答案 2 :(得分:0)

基于道格·史蒂文森(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, { ... });

答案 3 :(得分:0)

完成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