Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Flutter Firestore getRecord by Value and Output

First, apologies I am a total newb to Flutter, Dart & Firestore and despite trying to follow many tutorials I am stuck.

I am trying to retrieve a Firestore collection record by a specific value.

I have a service dart class which runs the query.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

import 'package:cloud_firestore/cloud_firestore.dart';

class WaypointService {

  getWaypointById(int wpCheckPointId) {
    return FirebaseFirestore.instance
        .collection("waypoints")
        .where("CheckPoint", isEqualTo: wpCheckPointId)
        .get();
  }

}

This service is passed an integer from a constant in a constants file. The screen that calls the service is:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:lhgth/services/waypoint_service.dart';

class WaypointScreen extends StatelessWidget {
  const WaypointScreen({ super.key, required this.wpFirebaseID });

  final int wpFirebaseID;

  @override
  Widget build(BuildContext context) {
    var waypoint;
    WaypointService().getWaypointById(wpFirebaseID).then((QuerySnapshot wayPoint) {
      if (wayPoint.docs.isNotEmpty) {
        waypoint = wayPoint.docs.first.data();
        print(waypoint); //##1
      }
    });

    print(waypoint); //##2

    return Container(
      padding: EdgeInsets.all(8),
      child: Scaffold(
        backgroundColor: Colors.white,
        body: Container(

        ),
      )
    );
  }
}

The issue I have is that the print statement ##1 is outputting what looks to be a JSON value:

{
  Radius: 25,
  Long: 50.9491835, 
  Info: Text,
  Lat: 0.7317906,
  CheckPoint: 1,
  Name: Waypoint Name
}

However, the second print ##2 returns a NULL and so I am not sure how I would work with the data returned from the query in the view itself.

Any guidance would be helpful.

>Solution :

That’s totally normal, the get() method is an async method you have to wait before it returns the value.

The second print ##2 returns null because it called before the getWaypointById method finishes.

First: make your getWaypointById method as Future like this:

Future<QuerySnapshot> getWaypointById(int wpCheckPointId) {
    return FirebaseFirestore.instance
        .collection("waypoints")
        .where("CheckPoint", isEqualTo: wpCheckPointId)
        .get();
}

Then: instead of doing tests in the build method, you can test in an external method like this:

test() async {
    var waypoint;
    var results = await getWaypointById(wpFirebaseID);
    if (results.docs.isNotEmpty) {
      waypoint = results.docs.first.data();
    }
    print(waypoint);
  }

Then you can call the test method in the build.

To show the value on the screen you can use FutureBuilder:

class WaypointScreen extends StatelessWidget {
  const WaypointScreen({ super.key, required this.wpFirebaseID });

  final int wpFirebaseID;

  @override
  Widget build(BuildContext context) {

    return Container(
        padding: EdgeInsets.all(8),
        child: Scaffold(
          backgroundColor: Colors.white,
          body: Container(
            child: FutureBuilder<QuerySnapshot>(
              future: WaypointService().getWaypointById(wpFirebaseID),
              builder: (context, snapshot) {
                if (snapshot.hasData && (snapshot.data?.docs.isNotEmpty?? false)) {
                  var waypoint = snapshot.data!.docs.first.data();
                  return Text(waypoint['Name']);
                } else {
                  return Text('Loading...');
                }
              },
            ),
          ),
        )
    );
  }
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading