-1

i have a problem with a Flutter application. I want to receive data from a firebase firestore by an Document id. The problem is, i cant replicate the data in one collection, so i have to use two collections.

My data ist a Measurement(String, String,..., List) MeasurementData(String,String,Number)

As far as i understand the Firestore i cant make such a list in one collection, so i have created a second one in whitch each document consists of three arrays. I also save the id from the Measurement Document where it belongs to. To use it in Flutter a use a StreamBuilder widget. For easer access i convert the document bevor using into a Dart Object. Because i have two Streams which should be converted to one Object i have a predessecor StreamMeasurement object which is basicly the same as the Measurement Object, but without the MeasurementData list, because this first needs to be created, instead it only saves a id for the measurementData Document. After that i use the Rx.zip2 to create an Measurement Object from the StreamMeasurement Object and add the List to have a complete object.

    Class Service
    
    /// The firebase instance
    FirebaseFirestore db = FirebaseFirestore.instance;
    
    ///Finds and returns a [Measurement] by its [id]
    Stream<Measurement> getById(String id) {
    Stream<StreamMeasurement> streamMeasurementStream =db.collection("measurements").doc(id)
         .snapshots().map((document) => StreamMeasurement.fromJson(document.data()!));
    return Rx.zip2(streamMeasurementStream, getMeasurementDataStreamById(id)
            , (StreamMeasurement streamMeasurement, List<MeasurementData> measurementData) {
                  Measurement measurement = Measurement.fromStreamMeasurement(streamMeasurement, measurementData);
                  if(measurement == null)
                  {
                      //TODO Write a concrete exception to throw and catch
                      throw Exception('Measurement Stream is null');
                  }
                  return measurement;
          }) ;
      }

     /// Returns a [Stream<List<MeasurementData>>] for a given Measurement id
    Stream<List<MeasurementData>> getMeasurementDataStreamById(String id)
      {
        return db.collection("measurementData").where("measurement", isEqualTo: id).
         snapshots().
         map((querySnapshot) => querySnapshot.docChanges)
        .expand((changes) => changes)
        .map((change) => change.doc).map((document) => MeasurementData.fromJson(document.data()!));
       }

    Class DetailScreen
    @override
    Widget build(BuildContext context) {
        MeasurementService measurementService = MeasurementService();
        Stream<Measurement> measurementstream = measurementService.getById(
        "GmfzveKeozkcfdlrk75s");
        return StreamBuilder<Measurement>(
            stream: measurementstream,
            builder: (BuildContext context, AsyncSnapshot<Measurement> snapshot) {
            if (snapshot.hasError) {
                print(snapshot.error);
                return Text('Something went wrong' + snapshot.error.toString());
            } 

            if (snapshot.connectionState == ConnectionState.waiting) {
               print(snapshot);
               return Text("Loading" + snapshot.connectionState.toString());
             }
             Measurement? measurement = snapshot.data;
             return SafeArea(

Print(snapshot) => I/flutter (19335): AsyncSnapshot(ConnectionState.waiting, null, null, null)

The result is, that the StreamBuilder is stuck in ConnectionState.waiting state if i use the getById(id) function

Sonac
  • 1
  • 2
  • Adding Information: The Error lays in the ´´´ Stream> getMeasurementDataStreamById(String id) ´´´ – Sonac Feb 17 '23 at 18:09
  • You're creating a brand-new stream on each call to build(). This can happen 60 times per second (120 on newer hardware)! Your stream keeps getting restarted on each build, so you'll burn through your free firebase tier pretty fast. My video on that is pretty good at explaining. https://youtu.be/sqE-J8YJnpg – Randal Schwartz Feb 17 '23 at 20:01

1 Answers1

-1

Okay, ... Question solved. The problem was a unmatched whitespace before the id EDIT: I had hardcodet the ID manually in the database, while writing i had left an whitespace before id, that doesnt belongs there and so the request doesnt work like " 1234" should be "1234"

Sonac
  • 1
  • 2
  • please add more info, if you can please add some code. – Alan Bosco Feb 23 '23 at 10:32
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Alan Bosco Feb 23 '23 at 10:32