GeoFlutterFire icon indicating copy to clipboard operation
GeoFlutterFire copied to clipboard

Display query results on screen

Open guijacobus2 opened this issue 4 years ago • 11 comments

I have this code, to query through the collection, but I want it to display on my Screen.

Stream showNearbyCompanies() async* {
    var pos = await location.getLocation();

    GeoFirePoint point =
        geo.point(latitude: pos.latitude, longitude: pos.longitude);

    double distance = 30;

    double lat = 0.023323826086956514;
    double lon = 0.02926080000000002776;

    double lowerLat = point.latitude - (lat * distance);
    double lowerLon = point.longitude - (lon * distance);

    double greaterLat = point.latitude + (lat * distance);
    double greaterLon = point.longitude + (lon * distance);

    GeoPoint lesserGeoPoint = GeoPoint(lowerLat, lowerLon);
    GeoPoint greaterGeoPoint = GeoPoint(greaterLat, greaterLon);

    Query query = _firebaseFirestore
        .collection("Companies")
        .where("location", isGreaterThan: lesserGeoPoint)
        .where("location", isLessThan: greaterGeoPoint);

    yield query;
  }

Then, I have this StreamBuilder

Container(
            child: StreamBuilder(
              stream: showNearbyCompanies(),
              builder: (context, snapshot) {
                if (!snapshot.hasData) {
                  return Text("Loading");
                }
                return Text(snapshot.data); // This line is the problem, what widget should be here instead of Text()?
              },
            ),
          )

What is the correct Widget to display this on my screen? And I want to show only a few docs on the collection, like company name and imageURL, not email

guijacobus2 avatar Apr 10 '21 17:04 guijacobus2

Can you please give more data? What do you want to have on the screen and what is the problem?

awaik avatar May 23 '21 09:05 awaik

Can you please give more data? What do you want to have on the screen and what is the problem?

So, you know apps like uber eats, that shows the image name, image profile, menu on the client app? That’s what I’m trying. I have a collection called companies on my Firabase, with name image, and on the client app, I want to display the nearby costumized name and image on the client screen

guijacobus2 avatar May 23 '21 09:05 guijacobus2

Ok. Use any widgets you want. Just for example (you can create your own widget exactly as you have in design) you can try https://api.flutter.dev/flutter/material/ListTile-class.html

awaik avatar May 23 '21 10:05 awaik

Ok. Use any widgets you want. Just for example (you can create your own widget exactly as you have in design) you can try https://api.flutter.dev/flutter/material/ListTile-class.html

Ok, but my problem is, I can’t do that. I tried a lot of different ways, with streamBuilder, ListViews, I’m just trying to find an explanation on how to some sort of loop through the items on Firebase, that I did but always get an error similar to “Stream<DocumentList> Object not iterable”

guijacobus2 avatar May 23 '21 10:05 guijacobus2

can you please install the latest version and post here print(snapshot.data)

awaik avatar May 23 '21 10:05 awaik

Ok, this is where I am trying to display: Container( child: StreamBuilder( stream: showNearbyCompanies(), builder: (context, snapshot) { if (!snapshot.hasData) { return Text("Loading"); } return ListView( children: [ for (var item in snapshot.data) ListTile( title: Text( item["companyName"], ), ), // Or use item.data()["companyEmail"] ], ); }, ), ),

And this is the error I am getting:

type '_MapStream<QuerySnapshotPlatform, QuerySnapshot>' is not a subtype of type 'Iterable<dynamic>'

This is the result of print(snapshot.data):

Instance of '_MapStream<QuerySnapshotPlatform, QuerySnapshot>'

guijacobus2 avatar May 23 '21 11:05 guijacobus2

You should unwrap all possible responses. Please use an example here https://firebase.flutter.dev/docs/firestore/usage/

After that, you will have exact error data. Right now it is not possible to understand the reason.

return FutureBuilder<DocumentSnapshot>(
      future: users.doc(documentId).get(),
      builder:
          (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {

        if (snapshot.hasError) {
          return Text("Something went wrong");
        }

        if (snapshot.hasData && !snapshot.data.exists) {
          return Text("Document does not exist");
        }

        if (snapshot.connectionState == ConnectionState.done) {
          Map<String, dynamic> data = snapshot.data.data();
          return Text("Full Name: ${data['full_name']} ${data['last_name']}");
        }

        return Text("loading");
      },
    );
  }

awaik avatar May 23 '21 11:05 awaik

Hey, @awaik, can you help me with one more thing?

I've done this, according to the GeoFlutterFire docs:

`Stream nearbyComp() async* { var pos = await location.getLocation();

GeoFirePoint point =
    geo.point(latitude: pos.latitude, longitude: pos.longitude);
final CollectionReference users =
    _firebaseFirestore.collection("Companies");

double radius = 10;
String field = 'location';

Stream<List<DocumentSnapshot>> stream = geo
    .collection(collectionRef: users)
    .within(center: point, radius: radius, field: field, strictMode: true);

yield stream;

}`

And I am trying to return it here:

Container( child: StreamBuilder( stream: nearbyComp(), builder: (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) { if (snapshot.hasError) { return Text('Something went wrong'); } if (snapshot.connectionState == ConnectionState.waiting) { return Text("Loading"); } print(snapshot.data); return new ListView( children: snapshot.data.docs.map((DocumentSnapshot document) { return new ListTile( title: new Text(document.data()['companyName']), subtitle: new Image.network(document.data()['url']), ); }).toList(), ); }, ), ),

But I get an error: he argument type 'StatelessWidget Function(BuildContext, AsyncSnapshot<DocumentSnapshot>)' can't be assigned to the parameter type 'Widget Function(BuildContext, AsyncSnapshot<dynamic>)'

So, on the builder, I change it to this:

builder: (BuildContext context, AsyncSnapshot snapshot)

But then, I get an error

Class '_AsBroadcastStream<List<DocumentSnapshot>>' has no instance getter 'docs'. Receiver: Instance of '_AsBroadcastStream<List<DocumentSnapshot>>' Tried calling: docs

Do you know what could be wrong, and a way to fix it?

guijacobus2 avatar Jun 01 '21 03:06 guijacobus2

Hey @guijacobus2 please try to remove .docs here snapshot.data.docs.map

awaik avatar Jun 01 '21 06:06 awaik

Hey, @awaik, Sorry for the late reply. Tried a few variations, but still don't know what to change. I did what you suggested, but it returns this error and I could not find a way around it.

type '(DocumentSnapshot) => ListTile' is not a subtype of type '(List<DocumentSnapshot>) => dynamic' of 'convert'

guijacobus2 avatar Jun 06 '21 23:06 guijacobus2

Tried chaning to this:

Container( child: StreamBuilder( stream: nearbyComp(), builder: (BuildContext context, AsyncSnapshot snapshot) { if (snapshot.hasError) { return Text('Something went wrong'); } if (snapshot.connectionState == ConnectionState.waiting) { return Text("Loading"); } return new ListView( children: snapshot.data.map((document) { // Adding snapshot.data.map<Widget> also returns error return new ListTile( title: new Text(document['companyName']), subtitle: new Image.network(document['url']), ); }).toList(), ); }, ), ),

But also returns this error message:

type 'Future<List<dynamic>>' is not a subtype of type 'List<Widget>'

guijacobus2 avatar Jun 10 '21 01:06 guijacobus2