如何让Firestore自动生成文档ID与存储的用户UID保持一致?
问题:Firestore文档ID与用户UID不一致的解决方法
当前在Flutter项目中使用Firestore存储用户游戏数据时,已将Games类的id字段设为用户UID,但Firestore自动生成的文档ID仍为随机短ID,导致文档ID与存储的UID不一致。需要将文档ID设置为用户UID,确保查询逻辑正常工作。
现有代码
1. 保存用户游戏数据代码
User? user = FirebaseAuth.instance.currentUser; onPressed: () { final games = Games( id: user!.uid, pc: pcController.text.trim(), board: boardController.text.trim(), real: realController.text.trim()); createGame(games); }, Future createGame(Games games) async { final json = games.toJson(); await docUser.set(json); }
上述代码实现用户输入数据后保存至Firestore的games集合,但未指定文档ID,导致Firestore自动生成随机ID。
2. Games数据类
class Games { String id; final String pc; final String board; final String real; Games( {required this.pc, required this.board, required this.real, this.id = ''}); Map<String, dynamic> toJson() => { 'pc': pc, 'id': id, 'board': board, 'real': real, }; static Games fromJson(Map<String, dynamic> json) => Games( pc: json['pc'], board: json['board'], real: json['real'], id: json['id'], ); }
3. 获取数据代码
List<String> docGameIDs = []; User? user = FirebaseAuth.instance.currentUser; getGamesId() async { await FirebaseFirestore.instance .collection('games') .where('id', isEqualTo: user?.uid) .get() .then((snapshot) { docGameIDs = []; for (var element in snapshot.docs) { docGameIDs.add(element.reference.id); } }); } FutureBuilder( future: getGamesId(), builder: (context, snapshot) { return ListView.builder( itemCount: docGameIDs.length, itemBuilder: (context, index) { return Container( child: GetGames(documentId: docGameIDs[index]), ); }, ); }, ),
4. GetGames组件代码
class GetGames extends StatelessWidget { final String documentId; const GetGames({super.key, required this.documentId}); @override Widget build(BuildContext context) { CollectionReference users = FirebaseFirestore.instance.collection('games'); return FutureBuilder<DocumentSnapshot>( future: users.doc(documentId).get(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.done) { Map<String, dynamic> data = snapshot.data!.data() as Map<String, dynamic>; return Center( child: Text( '${data['pc']}', ), ); } return const Text(''); }, ); } }
解决方案
核心是在保存数据时明确指定Firestore文档ID为用户UID,修改createGame方法即可实现:
Future createGame(Games games) async { final json = games.toJson(); // 直接将文档ID设置为用户UID(即games.id) await FirebaseFirestore.instance .collection('games') .doc(games.id) // 关键:用用户UID作为文档ID .set(json); }
额外优化建议
- 由于文档ID已经等于用户UID,后续查询无需再使用
where条件,直接通过doc(user.uid).get()获取数据即可,查询效率更高:// 优化后的获取数据逻辑(单文档场景) FutureBuilder<DocumentSnapshot>( future: FirebaseFirestore.instance.collection('games').doc(user?.uid).get(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.done && snapshot.hasData) { Map<String, dynamic> data = snapshot.data!.data() as Map<String, dynamic>; return Center(child: Text('${data['pc']}')); } return const Text('加载中...'); }, ) - 如果不需要在文档内存储重复的
id字段,可以从Games类的toJson方法中移除'id': id,减少冗余数据。
内容的提问来源于stack exchange,提问作者KKot
相关产品推荐
相关产品推荐

