如何在Map类型字段中生成Firestore风格的唯一ID作为键?
问题描述
原有数据结构
Countries (Collection) | --- 5nHsOxXPPenciyejILWP (Document) | --- Country Name (Map) | --- en (String) => Germany --- ar (String) => ألمانيا --- es (String) => Alemania --- it (String) => Germania --- de (String) => Deutschland --- ru (String) => Германия --- Cities (Map) | --- Berlin (String) => Berlin --- Munich (String) => Munich --- Frankfurt (String) => Frankfurt Posts (Collection) | --- RhwFwkvSZ2WCh2K1O7xg (Document) | --- Title (String) => ... --- Description (String) => ... --- Country ID (String) => 5nHsOxXPPenciyejILWP --- City ID (String) => Berlin
需求说明
在Cities字段中,希望使用类似b4ejx8nUIFrXE0EkVrbs的唯一ID作为键,而非城市名称。
当前实现为Berlin (String) => Berlin,期望调整为b4ejx8nUIFrXE0EkVrbs (String) => Berlin,同时Posts集合中的City ID (String)需对应存储b4ejx8nUIFrXE0EkVrbs,而非Berlin。
如果通过在Countries集合下创建子集合实现该需求,每个城市都会生成唯一ID,但该方案会大幅增加读次数,无法仅通过1次读操作获取数据。
请问是否有方法可以生成类似SKwFaGBYimiFBLUbZ9Oe、aXNTJsW6f6nTOsU7NBNO、EG1lo3Bbcnv9SJwLUGt5、q4QdEz3QPpvWu39gwpuK格式的唯一ID,替代城市名称作为Map的键?
解决方案
你需要的这种20位随机字符串ID就是Firestore自动生成文档ID的标准格式,完全可以在本地生成,不需要创建子集合,也不会增加额外的读次数:
- 如果你使用官方Firebase SDK,直接调用内置的ID生成方法即可,该方法为本地运算,不会产生任何额外的接口请求或读写开销:
- Web/Node.js 环境调用代码:
const cityUid = db.collection('any').doc().id - Android 环境调用代码:
val cityUid = FirebaseFirestore.getInstance().collection("any").document().id - iOS 环境调用代码:
let cityUid = Firestore.firestore().collection("any").document().documentID
- Web/Node.js 环境调用代码:
- 如果你不希望依赖Firebase SDK,也可以自行实现该ID生成逻辑:从大小写英文字母、数字共62个字符的字符集中随机抽取20位拼接即可,该ID的冲突概率极低,完全满足常规业务场景的使用需求。
调整后你的数据结构如下,仍然可以通过1次读请求获取单个国家下的所有城市数据:
Countries (Collection) | --- 5nHsOxXPPenciyejILWP (Document) | --- Country Name (Map) | --- en (String) => Germany --- ar (String) => ألمانيا --- es (String) => Alemania --- it (String) => Germania --- de (String) => Deutschland --- ru (String) => Германия --- Cities (Map) | --- b4ejx8nUIFrXE0EkVrbs (String) => Berlin --- aXNTJsW6f6nTOsU7NBNO (String) => Munich --- EG1lo3Bbcnv9SJwLUGt5 (String) => Frankfurt Posts (Collection) | --- RhwFwkvSZ2WCh2K1O7xg (Document) | --- Title (String) => ... --- Description (String) => ... --- Country ID (String) => 5nHsOxXPPenciyejILWP --- City ID (String) => b4ejx8nUIFrXE0EkVrbs
内容的提问来源于stack exchange,提问作者Taha Sami
相关产品推荐
相关产品推荐

