0

I could do something like..

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

But for this there is a chance where the generateID() will repeat the same string...Causing a document to be overwritten ...

So what im currently doing is to check if the generatedID already exist in the collection or not

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

So can firestore automatically create a document with its auto-ID and of specific length.... Or is this the only way to do it... to check if the id exist and then set if it doesn't ! ..?

Ibrahim Ali
  • 2,083
  • 2
  • 15
  • 36
  • Is this Javascript or Dart? I'm guessing Javascript based on the arrow function – touch my body Apr 09 '21 at 14:55
  • This is dart... – Ibrahim Ali Apr 09 '21 at 14:58
  • this has nothing to do with the language... i just want to know whether firestore has a feature when u can specify the length of its auto generated ID.... if it doesnt then is this the best way to do it.. where u check if the id exist in the collection or not then add the document... – Ibrahim Ali Apr 09 '21 at 15:09
  • Is having an ID with a specific length a hard requirement (absolutely mandatory)? If it is not a hard requirement you can rely on the Firestore mechanism to automatically generate IDs: the IDs are statistically guaranteed to be unique. – Renaud Tarnec Apr 09 '21 at 15:10
  • Yes it is a requirement... I am using it as a reference .. and 20 digits is too lengthy.. – Ibrahim Ali Apr 09 '21 at 15:15
  • 1
    You may adapt the Firestore algorithm to a shorter length: https://github.com/firebase/firebase-js-sdk/blob/master/packages/firestore/src/util/misc.ts#L27. From Frank's answer: https://stackoverflow.com/questions/46618719/firestore-are-ids-unique-in-the-collection-or-globally/46621206#46621206 – Renaud Tarnec Apr 09 '21 at 15:16

1 Answers1

0

The cloud_firestore API generates a random ID on the client device, so there's no guarantee the builtin CollectionReference.add function won't overwrite your data.

The method you're currently using will ensure you're creating a new document every time, but it doesn't prevent a User from overwriting this data. If someone tried to put a document there, that write will succeed unless you explicitly deny it server-side.

The only way to guarantee this data isn't overwritten is to add Security Rules.

One way to do this is to give all of your documents creation timestamps, and ensure that the affected update rules check to make sure this field isn't modified. In the app, this would be about twice as fast as your current method, since it only involves one read/write operation.

To do this, your create function would look something like this:

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)
}

...and your security rules would look something like this:

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

Also, it's worth noting that 5 is small enough to lead to collisions in a somewhat large collection. The odds of an ID already existing reaches 50% once there's about 30,000 documents in a collection.

touch my body
  • 1,634
  • 22
  • 36