Как передать один идентификатор документа Firestore другому классу на основе выбора с использованием Flutter / Dart?

Я пытаюсь создать функцию, используя флаттер, чтобы, когда пользователь выбирает миниатюрное изображение поездки, он переходит на страницу с более подробной информацией о выбранной им поездке. Я пытаюсь сделать запрос к базе данных Firestore как можно меньше, поэтому я пытался получить идентификатор документа из одного снимка запроса и передать его в класс IndividualTripPackage. Я пробовал этот подход множеством способов, но все они потерпели неудачу. Я также посмотрел на другие решения, размещенные людьми на SO, и я не смог заставить их работать для моего конкретного случая. Что я делаю неправильно? Я новичок, чтобы трепетать, поэтому, если у вас есть идеи о других подходах или более эффективных решениях, я открыт для предложений.

Класс TripPackages:

class _TripPackagesState extends State<TripPackages> {
  @override
  Widget build(BuildContext context) {
 //Some other code......
            child: SingleChildScrollView(
              child: StreamBuilder<QuerySnapshot>(
                stream:
                    Firestore.instance.collection('trip_package').snapshots(),
                builder: (BuildContext context,
                    AsyncSnapshot<QuerySnapshot> docSnapshot) {
                  if (!docSnapshot.hasData) return const Text('Loading...');
                  final int docCount = docSnapshot.data.documents.length;
                  return GridView.builder(
                    shrinkWrap: true,
                    primary: false,
                    scrollDirection: Axis.vertical,
                    itemCount: docCount,
                    itemBuilder: (_, int index) {
                      DocumentSnapshot document =
                          docSnapshot.data.documents[index];
                      return GestureDetector(
                        onTap: () => Navigator.push(
                          context,
                          MaterialPageRoute(
                            builder: (_) => IndividualTripPackage(
                                docID: docSnapshot.data.documents[index]),
                          ),
    //Some other code .....
  }
}

IndividualTripPackage Class:

class IndividualTripPackage extends StatefulWidget {
  DocumentSnapshot docID;
  IndividualTripPackage({this.docID});
  @override
  _IndividualTripPackageState createState() => _IndividualTripPackageState();
}

class _IndividualTripPackageState extends State<IndividualTripPackage> {
  @override
  Widget build(BuildContext context) {
    final String docID = widget.docID.data['docID'];
    return Material(
      child: SafeArea(
        child: LayoutBuilder(
          builder: (BuildContext context, BoxConstraints viewportConstraints) {
            return SingleChildScrollView(
              child: ConstrainedBox(
                constraints: BoxConstraints(minHeight: viewportConstraints.maxHeight),
                child: StreamBuilder(
                    stream: Firestore.instance.collection('trip_package').document('docID').snapshots(),
                    builder: (context, snapshot) {
                      if (!snapshot.hasData) {
                        return Text('Loading data....Please wait...');
                      } else {
                        final int itemCount = snapshot.data.document('docID').data['itineraryItems'].length;
                        return Column(...);
                      }
                    }),
      //Some more code........
  }
}

Всего 1 ответ


Хорошо, я надеюсь, что это отвечает на ваш вопрос!

Я использовал такой метод для своего приложения, и мне кажется, что он работает. Конечно, вы захотите настроить имена классов и другой код по своему вкусу, но, надеюсь, это то, что вы пытаетесь сделать.

Миниатюра поездки

import 'package:flutter/material.dart'

import 'package:cloud_firestore/cloud_firestore.dart'
import 'package:my_test_project/screens/detail.dart'

class Thumbnail extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _ThumbnailState();
}

class _ThumbnailState extends State<Thumbnail> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        automaticallyImplyLeading: false,
        title: Text(
          'Thumbnail'
        ),
      ),
      body: ListView(
        children: <Widget>[
          StreamBuilder<QuerySnapshot>(
            stream: Firestore.instance.collection('trips').snapshots(),
            builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
              if (snapshot.hasError) return Text('Error: ${snapshot.error}');
              if (!snapshot.hasData) return Container(
                child: Center(
                  child: CircularProgressIndicator()
                ),
              );
              return Column(
                children: snapshot.data.documents.map((doc) {
                  return GestureDetector(
                    onTap: () {
                      var docId = doc.documentID;
                      Navigator.push(context, MaterialPageRoute(builder: (context) => Detail(docId)));
                    },
                    child: Container(
                      child: Image(
                        image: NetworkImage(
                          doc.data['photo']
                        ),
                      ),
                    ),
                  );
                }).toList(),
              );
            },
          )
        ],
      )
    );
  }
}

Детали поездки

import 'package:flutter/material.dart'
import 'package:cloud_firestore/cloud_firestore.dart'

class Detail extends StatefulWidget {

  final docId;
  Detail(this.docId);

  @override
  State<StatefulWidget> createState() => _DetailState(docId);
}

class _DetailState extends State<Detail> {

  final docId;
  _DetailState(this.docId);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(
          'Detail'
        ),
      ),
      body: ListView(
        children: <Widget>[
          StreamBuilder<DocumentSnapshot>(
            stream: Firestore.instance.collection('trips').document(docId).snapshots(),
            builder: (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
              if (snapshot.hasError) return Text('Error: ${snapshot.error}');
              if (!snapshot.hasData) return Container(
                child: Center(
                  child: CircularProgressIndicator()
                ),
              );
              return Column(
                children: <Widget>[
                  Container(
                    child: Text(
                      snapshot.data['title'],
                      style: TextStyle(
                        fontSize: 24.0
                      ),
                    ),
                  ),
                  Container(
                    child: Image(
                      image: NetworkImage(
                        snapshot.data['photo']
                      ),
                    ),
                  ),
                  Container(
                    child: Text(
                      snapshot.data['body']
                    )
                  )
                ],
              );
            },
          )
        ],
      ),
    );
  }
}

По сути, я передаю переменную на следующий экран с идентификатором документа для использования в потоке DocumentSnapshot.


Есть идеи?

10000