I want to Navigate to another page and parse with firestore data but how do I do that when I am using MaterialPageRoute?

Issue

I want to navigate from Products Page to a ProductDetail page but I am using data directly from firebase firestore. What do I put in the MaterialPageRoute as the arguments? I am also using StreamBuilder to get data snapshot from firebase.
Below is the code. This is the products page.

class PopularRecipes extends StatefulWidget {
  const PopularRecipes({Key key}) : super(key: key);

  @override
  _PopularRecipesState createState() => _PopularRecipesState();
}

class _PopularRecipesState extends State<PopularRecipes> {
  final Stream _productStream =
      FirebaseFirestore.instance.collection('products').snapshots();
  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      mainAxisAlignment: MainAxisAlignment.start,
      children: [
        Padding(
          padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 20),
          child: CustomText(
            text: 'Popular Recipes',
            size: 20,
          ),
        ),
        Container(
          height: 500,
          child: StreamBuilder(
              stream: _productStream,
              builder: (context, snapshot) {
                if (snapshot.data == null)
                  return Center(
                    child: CircularProgressIndicator(
                      backgroundColor: Colors.teal,
                    ),
                  );
                return ListView.builder(
                    itemCount: snapshot.data.docs.length,
                    itemBuilder: (context, index) =>
                        _popularWidget(context, snapshot.data.docs[index]));
              }),
        ),
      ],
    );
  }

  Widget _popularWidget(BuildContext context, DocumentSnapshot document) {
    return Stack(
      children: [
        Container(
          margin: EdgeInsets.fromLTRB(40, 5, 20, 5),
          height: 160,
          width: double.infinity,
          decoration: BoxDecoration(
              color: Colors.white, borderRadius: BorderRadius.circular(20)),
          child: Padding(
            padding: const EdgeInsets.fromLTRB(100, 20, 10, 20.0),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    GestureDetector(
                      onTap: () => Navigator.push(context,
                          MaterialPageRoute(builder: (_) => DetailsScreen())),
                      child: Container(
                        width: 160,
                        child: Text(
                          document['name'],
                          style: TextStyle(
                              fontSize: 19.0, fontWeight: FontWeight.w600),
                          overflow: TextOverflow.ellipsis,
                          maxLines: 2,
                        ),
                      ),
                    ),
                    Column(
                      children: [
                        CustomText(
                          text: 'Ush.',
                          size: 14,
                          color: Colors.grey,
                        ),
                        CustomText(
                          text: document['price'],
                        ),
                      ],
                    )
                  ],
                ),
                RatingBarIndicator(
                  rating: document['rating'].toDouble(),
                  itemBuilder: (context, index) => Icon(
                    Icons.star,
                    color: Colors.amber.shade200,
                  ),
                  itemCount: 5,
                  itemSize: 15.0,
                  unratedColor: Colors.grey.shade300,
                  direction: Axis.horizontal,
                ),
                SizedBox(
                  height: 10,
                ),
                Container(
                  height: 40,
                  child: ListView(
                    scrollDirection: Axis.horizontal,
                    children: [
                      Row(
                        children: [
                          for (var tag in document['tags'])
                            Container(
                              decoration: BoxDecoration(
                                borderRadius: BorderRadius.circular(6),
                                color: Colors.grey.shade200,
                              ),
                              margin: EdgeInsets.only(right: 4),
                              child: Padding(
                                padding: const EdgeInsets.symmetric(
                                    horizontal: 8.0, vertical: 6),
                                child: Text(
                                  tag.toString(),
                                  style: TextStyle(
                                    fontSize: 14,
                                  ),
                                  textAlign: TextAlign.center,
                                ),
                              ),
                            )
                        ],
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ),
        ),
        Positioned(
          top: 10,
          left: 20,
          bottom: 10,
          child: GestureDetector(
            onTap: () => Navigator.push(
                context, MaterialPageRoute(builder: (_) => DetailsScreen())),
            child: ClipRRect(
              borderRadius: BorderRadius.circular(20),
              child: Image.network(
                document['image'],
                width: 110,
                fit: BoxFit.cover,
              ),
            ),
          ),
        )
      ],
    );
  }
}

This is the DetailsScreen page I want to go to when I click a specific product card.

class DetailsScreen extends StatefulWidget {
  const DetailsScreen({Key key}) : super(key: key);

  @override
  _DetailsScreenState createState() => _DetailsScreenState();
}

class _DetailsScreenState extends State<DetailsScreen> {
  @override
  Widget build(BuildContext context) {
    return Text(document['name']);
  }
}

How do I pass data from the previous page to the details page with MaterialPageRoute when working with firebase data? Thank you.

Solution

In your DetailsScreen page add the product variable

class DetailsScreen extends StatefulWidget {
  final DocumentSnapshot product;
  const DetailsScreen({Key key, @required this.product}) : super(key: key);

  @override
  _DetailsScreenState createState() => _DetailsScreenState();
}

class _DetailsScreenState extends State<DetailsScreen> {
  @override
  Widget build(BuildContext context) {
    return Text(widget.product['name']);
  }
}

And inside the onTap:

GestureDetector(
  onTap: () => Navigator.push(context,
     MaterialPageRoute(builder: (_) => DetailsScreen(document))), //pass the product

Answered By – Lucas Josino

Answer Checked By – Gilberto Lyons (FlutterFixes Admin)

Leave a Reply

Your email address will not be published.