Home > Enterprise >  Getting One-Time Read Data From Nested Firestore in Flutter
Getting One-Time Read Data From Nested Firestore in Flutter

Time:09-21

I'm currently trying to make an app that need to read data just for one time from a nested Firestore Database.

Here's my currently working code

FirebaseFirestore firestore = FirebaseFirestore.instance;
    CollectionReference users = firestore.collection('users');
    FirebaseAuth _auth = FirebaseAuth.instance;

    FutureBuilder getTheData = FutureBuilder<DocumentSnapshot>(
      future: users.doc(_auth.currentUser!.uid).get(),
      builder:
          (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
        if (snapshot.hasError || (snapshot.hasData && !snapshot.data!.exists)) {
          return Text("Something went wrong");
        }
        if (snapshot.connectionState == ConnectionState.done) {
          Map<String, dynamic> data =
              snapshot.data!.data() as Map<String, dynamic>;

          String _condition = data['condition'];
          String _descCondition = data['descCondition'];
          int _percentageValue = data['percentageValue'];

          return defaultDraw(
            condition: _condition,
            descCondition: _descCondition,
            percentageValue: _percentageValue,
          );
        }

        return defaultDraw(
          condition: "Loading",
          descCondition: "",
          percentageValue: 0,
        );
      },
    );

and it's able to read this data (condition, descCondition, and percentageValue) : enter image description here

but when I'm trying to read this data : enter image description here Which is another collection inside of the previous document (a collection named 'adviceData' with random document ID that I'm trying to read), I'm getting an error like this :

enter image description here

Here's my code :

FirebaseFirestore firestore = FirebaseFirestore.instance;
    CollectionReference users = firestore.collection('users');
    FirebaseAuth _auth = FirebaseAuth.instance;

    FutureBuilder _getParameterData = FutureBuilder<DocumentSnapshot>(
      future: users
          .doc(_auth.currentUser!.uid)
          .collection('adviceData')
          .doc()
          .get(),
      builder:
          (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
        if (snapshot.hasError || (snapshot.hasData && !snapshot.data!.exists)) {
          return Text("Something went wrong");
        }
        if (snapshot.connectionState == ConnectionState.done) {
          Map<String, dynamic> data =
              snapshot.data!.data() as Map<String, dynamic>;

          String _advicePhLow = data['advicePhLow'];
          String _advicePhHigh = data['advicePhHigh'];
          String _adviceTempLow = data['adviceTempLow'];
          String _adviceTempHigh = data['adviceTempHigh'];
          String _adviceHeightLow = data['adviceHeightLow'];
          String _adviceHeightHigh = data['adviceHeightHigh'];

          return drawParameter(
            advicePhLow: _advicePhLow,
            adviceTempLow: _adviceTempLow,
            adviceHeightLow: _adviceHeightLow,
          );
        }

        return drawParameter();
      },
    );

and my question is :

  1. Where did I make mistakes?
  2. Is there any better method to get a data from firestore?

Thanks in advance

CodePudding user response:

If you want to get all documents from the subcollection adviceData you would need to get a QuerySnapshot like here:

FutureBuilder<QuerySnapshot>(
      future: users
          .doc(_auth.currentUser!.uid)
          .collection('adviceData')
          .get(),
      builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
        if (snapshot.hasError) {
          return Text('Something went wrong');
        }

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

        return ListView(
          children: snapshot.data!.docs.map((DocumentSnapshot document) {
          Map<String, dynamic> data = document.data()! as Map<String, dynamic>;
            return ListTile(
              title: Text(data['full_name']),
              subtitle: Text(data['company']),
            );
          }).toList(),
        );
      },
    );
  }

If you want to get a single document from that subcollection you would need to define the id of that specific document:

 FutureBuilder _getParameterData = FutureBuilder<DocumentSnapshot>(
      future: users
          .doc(_auth.currentUser!.uid)
          .collection('adviceData')
          .doc('documentID') // here
          .get(),
      builder:

You can find more about both methods here.

  • Related