【问题标题】:Specify format for autogenerated Firestore document Ids指定自动生成的 Firestore 文档 ID 的格式
【发布时间】:2021-07-10 17:28:50
【问题描述】:

我正在创建一个小游戏,人们可以使用六位数的密码加入房间。每个房间都由 Firestore 集合中的一个文档表示,其中房间 pin 是房间文档的 ID。

我最初的想法是随机生成一个六位数的 pin 并检查是否存在具有该 id 的文档。如果是,则使用生成的 pin 创建一个新文档,如果不是,则生成一个新 pin 并检查该 id 是否可用。这种方法会起作用,但是如果运气不好,它可能会导致对数据库产生大量不必要的请求。

因此,我的问题是:是否可以指定自动生成的 id 的格式?或者,如果不可能,有没有办法获取所有文档 id 以在本地检查 id 是否存在?

【问题讨论】:

  • @Frank 提到的重复 ID 的可能性很高,尤其是只有 6 位数字。我建议考虑增加 PIN 的长度或坚持使用 Firestore ID。如果您只需要带有数字的唯一 ID,uuid-int 是另一种选择。

标签: firebase google-cloud-firestore


【解决方案1】:

您无法指定 Firestore SDK 生成的自动 ID 的格式。它们是纯随机的,并且具有一定数量的熵,可以在统计上保证不会发生冲突(两个客户端生成相同 ID 的机会非常小),并最大限度地减少热点的机会(在编写大量文档或索引时创建)值到磁盘上的相同区域)。

您可以生成任何您想要的自动 ID 格式。您只需要接受更高的冲突机会,就像您已经做过的那样,并且当文档位于磁盘上的同一区域时,您可能会遇到热点。

【讨论】:

    【解决方案2】:

    您无法为自动生成的 ID 指定格式,但您可以检查是否存在具有相同 ID 的房间。如果是,则尝试新 ID,否则创建具有相同 ID 的房间。

    async function addRoom(roomId) {
        const roomRef = admin.firestore().collection("rooms").doc(roomId)
        if ((await roomRef.get()).exists) {
            return addRoom(generatePin())
        } else {
            await roomRef.set({ ... })
        }
        return `${roomId} created`
    }
    
    function generatePin() {
        return String(Math.floor(Math.random() * 999999) + 100000)
    }
    
    return addRoom(generatePin())
        .then(() => console.log("Room created"))
        .catch((e) => console.error(e))
    

    PS:这可能会以某种递归状态结束,所以我建议使用 Firestore 的 ID 或 uuid-int,如果您只需要数字 ID。

    【讨论】:

    • 这正是我现在正在做的,而且效果很好。我担心的是,在我找到一个有效的房间密码之前可能需要多次尝试,这会很快耗尽我的阅读配额。你认为一个有效的策略可能是获取所有现有的房间别针并在本地找到一个有效的吗?
    猜你喜欢
    • 2021-03-29
    • 2018-08-27
    • 2019-09-10
    • 2020-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-15
    相关资源
    最近更新 更多