【问题标题】:Add document to firestore with the auto generated ID and the ID to be of specific length使用自动生成的 ID 将文档添加到 Firestore,并且 ID 具有特定长度
【发布时间】:2021-07-05 10:52:05
【问题描述】:

我可以做类似的事情..

String generateID(int len) {
  const _chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz1234567890';
  return List.generate(len, (index) => _chars[Random().nextInt(_chars.length)]).join();
}
...
var docId = generateID(5)
usersRef.doc(docID).set();

但为此,generateID() 可能会重复相同的字符串...导致文档被覆盖...

所以我目前正在做的是检查 generatedID 是否已经存在于集合中

 usersRef.doc(docID).get()
  .then((docSnapshot) => {
    if (docSnapshot.exists) {
       // ....
    } else {
      usersRef.doc(docID).set() // create the document
    }
});

因此,firestore 可以自动创建具有其自动 ID 和特定长度的文档....或者这是唯一的方法...检查 id 是否存在,如果不存在则设置! ..?

【问题讨论】:

  • 这是 Javascript 还是 Dart?我猜是基于箭头函数的 Javascript
  • 这是飞镖……
  • 这与语言无关...我只想知道当您可以指定其自动生成的ID的长度时,firestore是否具有功能...。如果没有,那就是这个最好的方法..您检查集合中是否存在 id 然后添加文档...
  • 具有特定长度的 ID 是硬性要求(绝对强制性)吗?如果不是硬性要求,您可以依靠 Firestore 机制自动生成 ID:ID 在统计上保证是唯一的。
  • 您可以将 Firestore 算法调整为更短的长度:github.com/firebase/firebase-js-sdk/blob/master/packages/…。来自弗兰克的回答:stackoverflow.com/questions/46618719/…

标签: firebase google-cloud-firestore


【解决方案1】:

cloud_firestore API 在客户端设备上生成一个随机 ID,因此无法保证内置的 CollectionReference.add 函数不会覆盖您的数据。

您当前使用的方法将确保您每次都创建一个新文档,但它不会阻止用户覆盖此数据。如果有人试图将文档放在那里,除非您在服务器端明确拒绝,否则该写入将成功。

保证这些数据不被覆盖的唯一方法是添加安全规则。

执行此操作的一种方法是提供所有文档的创建时间戳,并确保检查受影响的更新规则以确保该字段未被修改。在应用程序中,这大约是您当前方法的两倍,因为它只涉及一次读/写操作。

为此,您的 create 函数应如下所示:

import 'package:cloud_firestore/cloud_firestore.dart';


Future create(String col, Map<String, dynamic> data) {
  String docId = generateID(5); // This should be longer
  data = {
    ...data,
    'cts': FieldValue.serverTimestamp(),
  };
  return FirebaseFirestore.instance
      .collection(col)
      .doc(docId)
      .set(data)
}

...您的安全规则如下所示:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {

    function cts_valid_for_create() {
        return request.time == request.resource.data.cts;
    }

    function cts_valid_for_update() {
      return resource.data.cts == null
        && request.resource.data.cts == resource.data.cts;
    }

    match /{document=**} {
      allow get, delete: if true;
      allow create: if cts_valid_for_create();
      allow update: if cts_valid_for_update();
    }
  }
}

另外,值得注意的是,5 小到足以在较大的集合中导致冲突。一旦集合中有大约 30,000 个文档,ID 已经存在的几率达到 50%。

【讨论】:

    猜你喜欢
    • 2018-07-10
    • 2022-01-21
    • 2019-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-04
    相关资源
    最近更新 更多