内容提要
本文介绍Firestore NoSQL数据库的CRUD操作。首先解释其数据模型:集合包含文档,文档以键值对存储,支持嵌套映射和子集合。然后通过任务管理应用示例,演示使用Firebase Web SDK v9+执行创建(addDoc/setDoc)、读取(getDoc/getDocs/onSnapshot)、更新(updateDoc/arrayUnion)和删除(deleteDoc/writeBatch)操作,并强调删除子集合需手动处理、安全规则和复合索引等注意事项。
延伸解读
从关系型数据库迁移的思维转变
Firestore 的文档模型与 SQL 表结构截然不同,文档无需统一字段,这为灵活开发提供了便利,但也意味着数据一致性需由应用层保证。若沿用关系型思维设计数据,容易导致查询复杂或数据冗余。建议在建模时优先考虑查询需求,而非实体关系,以充分利用 NoSQL 的灵活性。
子集合删除的陷阱与应对
Firestore 的 deleteDoc() 不会级联删除子集合,删除父文档后,子集合文档会变成孤立数据,占用存储且难以管理。文章提供了使用 writeBatch() 批量删除子集合文档再删除父文档的解决方案,并强调这是开发者必须手动处理的责任。在实际应用中,应设计清理机制或定期检查孤立数据。
安全规则与配额管理不可忽视
测试模式仅限开发初期,30天后规则自动拒绝所有请求。生产环境必须配置安全规则,且子集合需要单独的规则块。此外,每次 getDocs() 都会计费读取,应避免全量拉取后客户端过滤,尽量使用 where() 和 limit() 优化查询,防止配额超支。
Q&A
Firestore 的数据是如何组织的?
Firestore 是一个 NoSQL 文档数据库,数据组织围绕集合(collections)和文档(documents)两个核心概念。集合是文档的容器,文档以键值对形式存储数据,类似于 JSON 对象。文档可以包含嵌套的映射(maps)和子集合(subcollections),且不强制要求文档具有相同的字段。
在 Firestore 中,创建文档有哪两种方式?
创建文档有两种方式:使用 addDoc() 让 Firestore 自动生成文档 ID,或者使用 setDoc() 并指定自定义文档 ID。addDoc() 适用于不需要控制 ID 的场景,而 setDoc() 适用于需要自定义 ID 的场景。
如何从 Firestore 中读取单个文档或整个集合?
读取单个文档使用 getDoc() 并传入文档引用;读取整个集合使用 getDocs() 并传入集合引用。此外,可以使用 query() 结合 where、orderBy、limit 等条件进行过滤和排序,也可以使用 onSnapshot() 实现实时更新。
在 Firestore 中,如何更新嵌套字段和数组?
更新嵌套字段可以使用点号表示法,例如 updateDoc(docRef, { "metadata.priority": "low" })。更新数组时,应使用 arrayUnion() 和 arrayRemove() 来安全地添加或删除元素,避免并发冲突。
删除 Firestore 文档时,子集合会被自动删除吗?
不会。删除文档时,其子集合不会被自动删除,会导致孤立子集合。需要手动删除子集合中的文档,然后再删除父文档。可以使用 writeBatch() 批量删除子集合文档和父文档,确保原子性。
使用 Firestore 时,常见的错误有哪些?
常见错误包括:安全规则导致的权限错误(Missing or insufficient permissions)、传递 undefined 值导致 addDoc() 失败、组合 where 和 orderBy 时缺少复合索引、读取次数过多导致配额警告、删除文档后遗留孤立子集合。