AngularFire2 5.0 Firestore文档ID获取疑问及新增文档ID方法咨询
为什么Firestore获取文档ID看起来这么繁琐?
这个困惑其实挺普遍的,很多从实时数据库转过来的开发者都会有类似疑问——核心原因是Firestore和你之前熟悉的数据库在设计逻辑上有差异:
Firestore把文档的元数据(比如文档ID、创建/更新时间)和业务数据分开存储了。文档ID本质是文档引用(DocumentReference)的一部分,而非文档数据本身的字段。这种设计是为了避免数据冗余,让文档只专注于存储你的业务信息,同时也能保证元数据的一致性(比如ID不会被误修改)。而之前的实时数据库里,节点的key是和数据绑定在一起的,所以可以直接通过$key访问,这是两种数据库不同的设计思路导致的差异,并非Firestore故意复杂化。
你的当前实现有没有问题?
给Post模型加一个可空的id字段并存在文档里,不算错误,但确实不是最优解:
- 存在数据冗余:文档ID已经存在于引用中,再存一遍属于重复存储,浪费存储空间;
- 可能引发同步问题:如果不小心修改了文档里的
id字段,会导致和实际文档引用的ID不一致,后续操作容易出问题。
更合理的做法是:在模型里保留id字段(甚至可以设为非空),但不把它存入Firestore文档,而是在读取文档时,从DocumentSnapshot的id属性直接赋值给模型的id。举个代码示例(以Dart/Flutter为例):
// Post模型定义 class Post { final String id; final String title; final String content; Post({required this.id, required this.title, required this.content}); // 从Map转模型时,传入读取到的文档ID factory Post.fromMap(Map<String, dynamic> map, {required String id}) { return Post( id: id, title: map['title'] as String, content: map['content'] as String, ); } // 转Map时,不包含id字段 Map<String, dynamic> toMap() { return { 'title': title, 'content': content, }; } } // 读取文档的代码 final docSnapshot = await FirebaseFirestore.instance.collection('posts').doc('target-doc-id').get(); if (docSnapshot.exists) { final post = Post.fromMap(docSnapshot.data()!, id: docSnapshot.id); // 此时post.id就是文档的实际ID,无需从文档数据中读取 }
如何获取add方法新增文档的ID?
这个其实很简单,Firestore的add()方法会返回一个DocumentReference对象,你可以直接从这个对象的id属性拿到新增文档的ID。另外还有一种提前生成ID的方式,适合需要提前知道ID的场景(比如关联其他文档):
方式1:调用add后获取ID
// 调用add写入数据,返回文档引用 final docRef = await FirebaseFirestore.instance.collection('posts').add(post.toMap()); // 从引用中提取ID final newPostId = docRef.id; print('新增的Post ID是:$newPostId');
方式2:提前生成ID再写入
// 先获取一个空的文档引用,Firestore会自动生成随机ID final postsCollection = FirebaseFirestore.instance.collection('posts'); final newDocRef = postsCollection.doc(); // 不传入ID参数,自动生成ID final newPostId = newDocRef.id; // 用生成好的ID写入数据 await newDocRef.set(post.toMap());
两种方式都能轻松拿到ID,根据你的业务场景选择即可~
内容的提问来源于stack exchange,提问作者Reza
相关产品推荐
相关产品推荐

