name__
name__

Reputation: 79

how to access one specific document (in firestore) to display after ontap operation in flutter list tile

I have a firestore collection (countries) and I need to show only one document in it after I press on the tile but whatever I write inside the ontap function is giving me various errors. what do I do? here is my code

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:vola1/pageShow.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:async/async.dart';

class test extends StatelessWidget {
  const test({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: StreamBuilder(
        stream: FirebaseFirestore.instance
            .collection('countries')
            // .doc('nW9L4LGpn2MZVyiTyUII')
            .snapshots(),
        builder: (context, AsyncSnapshot<QuerySnapshot> querySnapshot) {
          if (querySnapshot.hasError) return Text('has some error');
          if (querySnapshot.connectionState == ConnectionState.waiting) {
            return CircularProgressIndicator();
          } else {
            // if (!snapshot.hasData) return Text('Loading data.. please wait..');
            final list = querySnapshot.data.docs;
            return ListView.builder(
              itemBuilder: (context, index) {
                return Container(
                  child: ListTile(
                    title: Text(list[index]['name']),
                    subtitle: Text(list[index]['description']),
                    contentPadding: EdgeInsets.all(20),
                    leading: Image.network(
                      list[index]['image'],
                      height: 200,
                      width: 80,
                    ),
                    onTap: () => {
                      Navigator.push(
                        context,
                        MaterialPageRoute(
                          builder: (context) => pageShow(list[index]),
                        ),
                      ),
                    },
                  ),
                  color: Colors.orangeAccent,
                );
              },
              itemCount: list.length,
            );
          }
        },
      ),
      appBar: AppBar(
        centerTitle: true,
        backgroundColor: Color.fromRGBO(255, 111, 82, 0.8),
      ),
    );
  }
}

enter image description here

enter image description here

this is code of the page I am navigating to

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:async/async.dart';

class pageShow extends StatelessWidget {
  const pageShow(list(index), {Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: StreamBuilder(
        stream: FirebaseFirestore.instance.collection('countries').get(),
        builder: (context, snapshot) {
          if (!snapshot.hasData) return Text('Loading data.. please wait..');
          return Column(
            children: <Widget>[
              Text(
                snapshot.data['name'],
                style: TextStyle(fontSize: 20),
              ),
              Text(
                snapshot.data['description'],
                style: TextStyle(fontSize: 20),
              ),
              Text(
                snapshot.data['cuisine'],
                style: TextStyle(fontSize: 20),
              ),
              Text(
                snapshot.data['tradition'],
                style: TextStyle(fontSize: 20),
              )
            ],
          );
        },
      ),
      appBar: AppBar(
        centerTitle: true,
        backgroundColor: Color.fromRGBO(255, 111, 82, 0.8),
      ),
    );
  }
}

after pressing on the tile I want it to display all the contents of the specific document in firestore.it would be very heplful.

Upvotes: 0

Views: 1689

Answers (1)

Dharmaraj
Dharmaraj

Reputation: 50920

Hello you don't need to use .snapshots() when fetching a single document. You can try the code below. Also I would suggest to keep the document ID as the country name in lower case so that you can use the query below.

FirebaseFirestore.instance
    .collection('countries')
    .doc("countryName")
    .get()
    .then((DocumentSnapshot documentSnapshot) {
      if (documentSnapshot.exists) {
        print('Document data: ${documentSnapshot.data()}');
        //Set the relevant data to variables as needed
      } else {
        print('Document does not exist on the database');
      }
    });

Here's another sample from the FlutterFire Documentation

However, if you do no want the country name as the document ID then you would have to store the country name in the doc as a field (lower case preferred as queries are case sensitive). Then you can make a request as follows:

FirebaseFirestore.instance
  .collection('countries')
  .where('countryName', isEqualTo: "theCountryNameUserClickedOn")
  .get()

Make sure to add the countryName field in the document in Firestore.

Upvotes: 1

Related Questions