0

When a new user signs up, there should be a property named userNo. which should be increased by 1 in each document, so that it would be easy to pick random users from db using that userNo. Basically, like each document holds a User number similar to Uid but not like Afhghdfh4hk545, it should be like userNo.23 and so one. If a new user signs up its userNo. should be 24. Here is what I have tried.

Stream dummy =
    await FirebaseFirestore.instance.collection('users').snapshots();
var doclength = await dummy.length;
var userNo = (dummy == null || dummy == 0) ? 1 : doclength;
FirebaseFirestore.instance
    .collection('users')
    .doc(currentUser.uid)
    .update({'userNo': userNo});
Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
  • 1
    It's not a good idea to assign an increasing identifier to sensible data. The IDs could be easily guessed then by someone who is not supposed to know them. Maybe you have to ask the question differently: ["How to get random documents in a collection"?](https://stackoverflow.com/questions/46798981/firestore-how-to-get-random-documents-in-a-collection#46801925) – 0x4b50 Dec 22 '20 at 16:07
  • Assigning monotonically increasing integers is not a very good pattern for data in Firestore, a it limits the scalability of writes of documents in a collection. – Doug Stevenson Dec 22 '20 at 16:11

2 Answers2

1

Alright, you'll need a "meta document" that has a field called something like "next_user_number".

Upon creating a new user, you check the number on that field and use it as the "UserNo" for the newest user.

And after that, you increase the "next_user_number" in the "meta document" by 1. (here you want to use FieldValue increment - search for "firestore increment" for how to do it.)

But... to be absolutely sure this will work even in cases when two users are signing up at the same time or other error-prone cases, make sure you use a "batch write".

A batch write means that both operations are done together, so both incrementing the "next_user_number" and creating the new user with the right "UserNo" number are going to be accurate. (search for "firesotre batch write" to learn more).

  • That almost solves the issue, but where do I get meta document. Firebase doesn't seem to have one. Will I have to write one and if yes then how? – KUMAR KESHAV Dec 22 '20 at 14:41
  • what I mean by "meta document" is a normal Firestore document you name differently than the others so you can easily retrieve it. It can be in the same collection or another collection. It's up to you. You create it manually at first then write the function that keeps updating it after each new user (.update()). You can also create AND update it using the (.set()) method with {merge:true} so it's never overwritten. – MarketerInCoderClothes Dec 22 '20 at 14:44
  • I know that approach and the same I have been doing for this. Even above in my code I have done the same I was wondering if anyone could write this as I am beginner in dart. – KUMAR KESHAV Dec 22 '20 at 14:49
  • If you don't have good transactions, this has the potential of failing when you least expect it (like under heavy load that you can't reproduce). – Randal Schwartz Dec 22 '20 at 17:38
0

Okay, I solved it after drinking mugs of coffee. To all of the future visitors you can get the exact length of documents in that particular collection and then use then keyword and extract the value and store it in int variable. Then you can use extractedValue.size as the userNo.

  • Don't forget that documents could be deleted. Then a new user would receive a `userNo` that has already been assigned to another user. You would need to remember the amount of deleted user documents. – 0x4b50 Dec 22 '20 at 16:02
  • Documents could be deleted only by the admin, users won't have right to perform that operation. Hence I would not delete those documents and if I need to block some user I will do that from console by blocking their device token from accessing our services. – KUMAR KESHAV Dec 22 '20 at 16:24
  • I agree but this does not address the problem of your solution. Further, if you have many user documents and you count them by fetching all available documents, you create read counts that raise your Firebase bill inefficient and unnecessarily. Unfortunately, Firebase does not offer any other possibility to count documents :-( – 0x4b50 Dec 22 '20 at 16:42
  • You are right. I completely agree but the thing is I am trying to start a social network startup so counting users is crucial for us. Firebase is great for startups no doubt and when we see the increment in our users we will shift to our own backend services along with database. So this sums up everything, I guess. – KUMAR KESHAV Dec 23 '20 at 06:14