You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 22:07:52