繁体   English   中英

如何从 Flutter 和 Firestore 中“Y”集合的文档 ID 查询“X”集合的文档

[英]How to query documents of 'X' collection from document id of 'Y ' collection in Flutter and Firestore

我在 firestore questionbookmark中有两个集合。

为了将问题保存到用户书签页面,我构建数据库的方法是将书签集合的文档docID设置为与问题 collections 文档docID相同,书签集合字段只是一个保存书签的用户的 uid我的结构看起来像这样,

这是我的书签收藏

在此处输入图像描述

这是我的问题集

在此处输入图像描述

这里书签文档ID ==问题文档ID

到目前为止,我已经使用了 streambuilder,但无法从书签集合中获取问题文档,这是我目前的代码,我没有得到如何从书签集合 docID 中获取问题文档

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:devcom/screens/detailsPage.dart';
import 'package:devcom/utils/responsive.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';

class Bookmark extends StatefulWidget {
  final User user;
  const Bookmark({Key? key, required this.user}) : super(key: key);

  @override
  State<Bookmark> createState() => _BookmarkState();
}

class _BookmarkState extends State<Bookmark> {
  @override
  void initState() {
    _currentUser = widget.user;
    super.initState();
  }

  late User _currentUser;
  // final db = FirebaseFirestore.instance;

  @override
  Widget build(BuildContext context) {
    final Stream<QuerySnapshot> _bmStreams = FirebaseFirestore.instance
        .collection('bookmark')
        .where("uid", isEqualTo: "${_currentUser.uid}")
        .snapshots(includeMetadataChanges: true);
    return StreamBuilder<QuerySnapshot>(
      stream: _bmStreams,
      builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
        if (snapshot.hasError) {
          return Text('Something went wrong');
        }
        if (snapshot.hasData == false)
          return Text(
              'Howdy ${_currentUser.displayName}!!, 404 clever: you havent posted in a while');

        if (snapshot.connectionState == ConnectionState.waiting) {
          return Text("Loading");
        }

        return Scaffold(
            appBar: AppBar(
              title: Text('My Questions'),
              leading: IconButton(
                  onPressed: () {
                    Navigator.pop(context);
                  },
                  icon: Icon(Icons.arrow_back_ios_new_rounded)),
            ),
            backgroundColor: Colors.white,
            body: Padding(
                padding: EdgeInsets.all(40),
                child: ListView.builder(
                  shrinkWrap: true,
                  itemCount: snapshot.data!.docs.length,
                  itemBuilder: (context, int index) {
                    final DocumentSnapshot data = snapshot.data!.docs[index];
                    if (!data.exists) {
                      print('not exists');
                    }
                    return Text(data['mydatahere']);
                  },
                )));
      },
    );
  }
}

是否可以嵌套 streambuilder 或我是否需要单独获取文件请帮助我在这方面陷入困境并且不知道如何使这项工作......

谢谢你,

是的,您可以嵌套 streamBuilder。

对于每个书签,我们获取与该 id 对应的问题。

将您的 listView 构建器替换为以下内容。

itemBuilder: (context, int index) {
  final DocumentSnapshot data = snapshot.data!.docs[index];
  if (!data.exists) print('not exists');
  // here we return the second StreamBuilder
  return StreamBuilder<DocumentSnapshot<Map<String, dynamic>>>(
    stream: FirebaseFirestore.instance
        .collection('question')
        .doc(data.id)
        .snapshots(),
    builder: (BuildContext context,
        AsyncSnapshot<DocumentSnapshot<Map<String, dynamic>>>
            qSnapshot) {
      if (qSnapshot.hasError) return Text('Something went wrong');
      if (qSnapshot.connectionState == ConnectionState.waiting)
        return Text("Loading");
      print(qSnapshot.data!.data()); // should print the question
      return Text(data['mydatahere']);
    },
  );
},

您的文档结构存在一些缺点。

  1. 如果 2 个用户为同一个问题添加书签,它将只保留他们的一个书签。 解决此问题的一个简单方法是使 uid(在书签集合中)成为一个 uid 数组。 如果用户为问题添加了书签,您可以使用FieldValue.arrayUnion(uid)将他添加到数组中,如果他取消书签,您可以使用FieldValue.arrayRemove(uid)删除他并为用户获取所有数据,您可以使用.where('uids', arrayContains: uid)
  2. 此外,在名为usersThatBookmarked的问题集合中简单地包含一个数组可能会更好,您可以在其中添加已为问题添加书签的用户。 这不是最佳的,但应该比我的第一个建议更好
  3. 还有,我觉得你不应该收藏stream书签。 用户在书签页面上时不应该添加书签。 因此,最好使用未来来获取书签集合。 这应该会提高性能。
  4. 为避免文档达到 1mb 限制并避免冲突 (1),您可以将bookmarks集合的文档 ID 用作uid + '_' + questionId (这可以防止用户为问题添加书签两次)。 然后将字段uidquestionId添加到每个bookmark文档。 您可以使用where('uid', isEqualTo: uid)获取并且questionId将是问题文档 ID。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM