Nicholas Aliabadi
Nicholas Aliabadi

Reputation: 63

How to create a custom short unique-id in Firebase-Database with many active users

My application is a game where I need each user to be able to create a unique, natural number ID code that can be bijectively converted to a "short string" the same way a url-shortener works. The "short string" part is very important to the game.

I thought about creating a child node with an auto-id key that stores the natural number index & short string and another child node that contains the natural number as the key and the previous auto-id key.

I'm worried about having a race condition in the unlikely event that two users create a new ID at the same time. Ideally, I'd like to be able to increment the IDs starting at 1000 to keep the short strings very short.

Does anyone know a good solution to this type of problem using firebase-database?

I want to keep the "short strings" under 6 characters in length and only use numbers, capital letters and hyphens. (so a 34 character alphabet, ommitting 1s, ls, Os and 0s for clarity)

Maybe this is not possible and I will have to use a 50 character alphabet to generate a random number and add it to every key.


One idea was to check the current highest key and generate a random number to add to that, but there is still no guarantee two users won't get the same number.


So far the only other idea I have to possibly prevent a race-condition if two users attempt to generate a new key at the same time is keeping an internal list of online users and in the child nodes of each user, create the keys and having a delay before posting to the database....requiring the users to check with all other users' requested keys.

This last idea seems convoluted and prone to errors, needing code to check the list every time a user reconnects in case they lost their connection last time they were online.

Upvotes: 5

Views: 5097

Answers (2)

Nicholas Aliabadi
Nicholas Aliabadi

Reputation: 63

So I finally came up with a solution for this problem.

I am also creating an Android version of the app, so will have to find the equivalent way to do this in Android.

What I did was used a transaction block to increment a counter. Every time the counter successfully increments, it runs a completion block which updates the corresponding child node.

The next problem occurred when the same user wanted to perform multiple increments at a time. (this doesn't happen very often, but it does happen)

The transaction blocks each get their own thread, but the completion blocks will queue up on the main thread, waiting for the transactions to all complete.

Using GCD I was able to give each increment operation its own thread by using a DispatchQueue. Now users can perform however many increments they need to and be guaranteed to have our unique HashId tracking code corresponding to their item.

I ended up getting some help on this in the Firebase Slack group....good place to go to find active discussions!

Cheers!

Upvotes: 0

matijse
matijse

Reputation: 66

hashids is a small script to convert a number into a short string and back (see http://hashids.org/).

This way you can simply use an increasing counter, and translate these to short strings.

I use this in Firebase by having a central "counter" node, which can only be incremented by 1 (use security rules). A client can increment this node by one using a transaction. The resulting number will be guaranteed unique for that client. (Note that the code in a transaction block can fire multiple times, if two clients fire the transaction exactly at the same time. So you need to use the final number that the transaction creates.)

The number that is unique for that client can then be used with hashids to create a short string that is also guaranteed to be unique.

Note: this doesn't solve the "problem" that users can guess the next ID. The short strings can be translated back to a number if you have the salt that is used to create the string. Then the next short string can easily be generated by using the hashids function. So if you create the short strings in your client, the salt is also known in the client and thus can be extracted by users.

Of course, this might not be a problem depending on your case.

Upvotes: 5

Related Questions