【问题标题】:How to pass a Firestore document from a stream to next page in Flutter?如何将 Firestore 文档从流中传递到 Flutter 中的下一页?
【发布时间】:2021-10-18 20:11:00
【问题描述】:

我有一个列表视图,其中每个项目都是来自 firestore 集合的一个文档。我想点击该项目并将文档信息传递到详细信息页面。

这就是我在第一个流中检索文档信息的方式:

child: Text(streamSnapshot.data.docs[index]['event_title'],

这就是我尝试将数据发送到下一页的方式:

child: GestureDetector(
                          onTap: () {
                            Navigator.pushNamed(context, EventPage.id, arguments: streamSnapshot.data.docs[index]);
                          },

我不知道如何接收传递的数据:

    class _EventPageState extends State<EventPage> {
  @override

final db = FirebaseFirestore.instance;
  Widget build(BuildContext context) {
    final args = ModalRoute.of(context)!.settings.arguments;
    return CupertinoPageScaffold(
      navigationBar: CupertinoNavigationBar(
        middle: Text('event_title'),
      ),
      child: Column(

我知道在下一页我需要一个 StreamBuilder,但是您对如何使该流仅显示传入的文档有任何见解吗?

【问题讨论】:

    标签: flutter flutter-routes flutter-streambuilder


    【解决方案1】:

    为什么不使用 Provider 呢?它将帮助您避免样板文件,并且当您使用流时,它将让您以更好的方式处理信息。检查一下here

    【讨论】:

    • 感谢您的意见。看起来 Riverpod 是提供程序的改进版本,可能是要走的路。您是否有任何关于如何执行此操作的资源指针或链接?我对编码很陌生,虽然我最终会弄明白,但可能需要一段时间。
    • 其实这就是我推荐你Provider的原因,你会更容易理解,我建议你同时阅读文档和查看youtube教程......这是我认为了解 Provider 的最佳方式,然后您可以迁移到 Riverpod(正如您所说,Riverpod 与 provider 具有相同的基础)
    • 因此,我在提供者和 Riverpod 的文档和 YouTube 教程中一直在努力,但我仍然没有找到我的问题的答案。我变得非常沮丧,答案可能就在我面前。能否请您回答我的问题,或指导我回答?主页显示了集合中 firebase 文档的列表视图。我需要点击一个文档并导航到包含该文档更多信息的详细信息页面。如何将两者联系起来?
    【解决方案2】:

    我已经找到了这个问题的答案。我确信有几种方法可以做到这一点,但这是我的:

    关键是将firestore文档ID传递到下一页。在此示例代码中,我将 streamSnapshot.data.docs[index].id.toString() 作为参数传递给自定义小部件。我已经在那个小部件中找到了我的命名路线。

    StreamBuilder(
        stream: FirebaseFirestore.instance
            .collection('events')
            .where('start_date', isGreaterThanOrEqualTo: DateTime.now())
            .snapshots(),
        builder: (context, AsyncSnapshot streamSnapshot) {
    
          if (!streamSnapshot.hasData) {
            return SizedBox(
              height: 250,
              child: Center(
                child: CircularProgressIndicator(),
              ),
            );
          } else
            return SizedBox(
              height: 250,
              child: ListView.builder(
                scrollDirection: Axis.horizontal,
                itemCount: streamSnapshot.data.docs.length,
                itemBuilder: (ctx, index) =>
    
                    EventListHorizontalTile(
    
                    //passes the document ID as a string down to the horizontally scrollable tile,
                    //where we push a named route with the docID string as an argument
    
                    firestoreDocID: streamSnapshot.data.docs[index].id.toString(),
    
                      image: streamSnapshot.data.docs[index]['main_image'],
                      name: streamSnapshot.data.docs[index]['name'],
                  ),
              ),
            );
        }),
    

    然后我创建了一个类,通过命名路由作为参数传递。

    class Events {
      final String firestoreDocID;
    
      Events({
        required this.firestoreDocID,
    
      });
    
    }
    

    现在,在我的 EventListHorizontalTile 小部件中:

    class EventListHorizontalTile extends StatelessWidget {
      const EventListHorizontalTile({
        Key? key,
    
        required this.name,
        this.firestoreDocID = '',
    
      }) : super(key: key);
    
      final String name;
      final String firestoreDocID;
    
      @override
      Widget build(BuildContext context) {
    return GestureDetector(
    
            onTap: () {
    
    //Here I am pushing a named route with an argument, using that Events class I made earlier.
    
              Navigator.pushNamed(context, EventPage.id, arguments: Events(firestoreDocID: firestoreDocID));
    
            },
    
    //child: The rest of the list tile widget
    
    ),
    

    现在我们必须在EventPage 中编写一些代码来接收参数。

    class EventPage extends StatefulWidget {
      const EventPage({
        Key? key,
      }) : super(key: key);
    
      static String id = 'EventPage';
    
      @override
      _EventPageState createState() => _EventPageState();
    }
    
    class _EventPageState extends State<EventPage> {
      @override
      Widget build(BuildContext context) {
    
    
    //This is how we receive the argument.
        final args = ModalRoute.of(context)!.settings.arguments as Events;
    
        return CupertinoPageScaffold(
          navigationBar: CupertinoNavigationBar(),
          child: SingleChildScrollView(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
    
    //Some text to see if the string made it.
                Text(args.firestoreDocID),
    
    ]),
    ),
    );
    }
    }
    

    就是这样!在新页面中获得该文档 ID 后,您可以像这样调用 Streambuilder

    StreamBuilder(
                  stream: FirebaseFirestore.instance
                      .collection('events')
                      .doc(args.firestoreDocID)
                      .snapshots(),
    

    【讨论】:

      猜你喜欢
      • 2020-05-02
      • 1970-01-01
      • 2019-04-26
      • 2023-03-30
      • 2021-12-04
      • 2020-12-05
      • 2021-12-16
      • 1970-01-01
      • 2019-03-20
      相关资源
      最近更新 更多