如何在具有许多活跃用户的 Firebase 数据库中创建自定义短唯一 ID

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

我的应用程序是一个游戏,我需要每个用户都能够创建一个唯一的自然数 ID 代码,该代码可以像 url-shortener 一样双射转换为 "short string"作品。 "short string"部分对游戏非常重要。

我想创建一个子节点,它有一个存储自然数索引和短字符串的自动标识键,以及另一个包含自然数作为键和前一个自动标识键的子节点。

我担心在两个用户同时创建新 ID 的不太可能发生的情况下会出现竞争条件。理想情况下,我希望能够增加从 1000 开始的 ID,以保持短字符串非常短。

有人知道使用 firebase-database 解决此类问题的好方法吗?

我想将 "short strings" 的长度控制在 6 个字符以内,并且只使用数字、大写字母和连字符。 (所以一个 34 个字符的字母表,为清楚起见省略了 1、ls、Os 和 0)

也许这是不可能的,我将不得不使用 50 个字符的字母表来生成一个随机数并将其添加到每个键中。


一个想法是检查当前最高密钥并生成一个随机数以添加到它,但仍然不能保证两个用户不会得到相同的数字。


到目前为止,如果两个用户试图同时生成一个新密钥,我唯一可能阻止竞争条件的另一个想法是在每个用户的子节点中保留在线用户的内部列表,创建密钥并在发布到数据库之前有延迟....要求用户检查所有其他用户请求的密钥。

最后一个想法似乎很复杂并且容易出错,每次用户重新连接时都需要代码来检查列表,以防他们上次在线时失去连接。

hashids 是一个将数字转换为短字符串并返回的小脚本(参见 http://hashids.org/)。

这样您就可以简单地使用递增计数器,并将它们转换为短字符串。

我在 Firebase 中通过中央 "counter" 节点使用它,该节点只能递增 1(使用安全规则)。客户端可以使用事务将此节点递增一个。生成的数字将保证对该客户唯一。 (请注意,如果两个客户端恰好同时触发交易,则交易块中的代码可以触发多次。因此您需要使用交易创建的最终编号。)

然后可以将对该客户端唯一的号码与 hashids 一起使用来创建一个短字符串,该字符串也保证是唯一的。

注意:这并没有解决 "problem" 用户可以猜测下一个 ID 的问题。如果您有用于创建字符串的 salt,则可以将短字符串转换回数字。然后可以很容易地使用 hashids 函数生成下一个短字符串。因此,如果您在客户端中创建短字符串,则 salt 在客户端中也是已知的,因此可以被用户提取。

当然,根据您的情况,这可能不是问题。

所以我终于想出了解决这个问题的方法。

我也在创建应用程序的 Android 版本,因此必须在 Android 中找到等效的方法来执行此操作。

我所做的是使用事务块来增加计数器。每次计数器成功递增时,它都会运行一个完成块来更新相应的子节点。

下一个问题发生在同一用户想要一次执行多个增量时。 (这种情况不常发生,但确实会发生)

事务块各自有自己的线程,但是完成块会在主线程上排队,等待事务全部完成。

使用 GCD,我能够通过使用 DispatchQueue 为每个增量操作提供自己的线程。现在,用户可以执行他们需要的任意数量的增量,并保证我们的唯一 HashId 跟踪代码对应于他们的项目。

我最终在 Firebase Slack 组中得到了一些帮助....这是寻找活跃讨论的好地方!

干杯!