26

I am wondering how to get data from firestore to my Flutter app using the StreamBuilder. I created the necessary Boilerplate code I have the widget built and working and in the below code headimageassetpath is nothing but a URL string which exists in the Firestore Database.

@override Widget build(BuildContext context) { return Scaffold( body: new StreamBuilder( stream: Firestore.instance.collection('Items').snapshots(), builder: (_, AsyncSnapshot<QuerySnapshot> snapshot) { var items = snapshot.data?.documents ?? []; return new Lost_Card( headImageAssetPath : snapshot.data.documents.map()(['url'],) ); }, ) 

My Firestore Database schema:

Full code:

import 'package:flutter/material.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; class LostPage extends StatefulWidget { @override _LostPage createState() => new _LostPage(); } class _LostPage extends State<LostPage> { //temp vars final String firebasetest = "Test"; //firestore vars final DocumentReference documentReference = Firestore.instance.document("Items/Rusty"); //CRUD operations void _add() { Map<String, String> data = <String, String>{ "name": firebasetest, "desc": "Flutter Developer" }; documentReference.setData(data).whenComplete(() { print("Document Added"); }).catchError((e) => print(e)); } @override Widget build(BuildContext context) { return Scaffold( body: new StreamBuilder( stream: Firestore.instance.collection('Items').snapshots(), builder: (_, AsyncSnapshot<QuerySnapshot> snapshot) { var items = snapshot.data?.documents ?? []; return new Lost_Card( headImageAssetPath : snapshot.data.documents.map()(['url'],) ); }, ) /*new Lost_Card( headImageAssetPath: "https://i.imgur.com/FtaGNck.jpg" , title: "Mega Dish", noro: "old", )*/, floatingActionButton: new FloatingActionButton( child: new Icon(Icons.add), onPressed: _add), ); } } class Lost_Card extends StatelessWidget { //All the card variables final String headImageAssetPath; final IconData icon; final Color iconBackgroundColor; final String title; final String noro; final int price; final ShapeBorder shape; Lost_Card({ this.headImageAssetPath, //used this.icon, this.iconBackgroundColor, this.title, //used this.noro, //used this.price, }); @override Widget build(BuildContext context) { // TODO: implement build return GridView.count( shrinkWrap: true, crossAxisCount: 2, children: <Widget>[ Card( child: Column( // mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Expanded( child: Stack( fit: StackFit.expand, children: <Widget>[ Container( height: MediaQuery.of(context).size.height / 4, width: MediaQuery.of(context).size.height / 2.5, child: DecoratedBox( decoration: BoxDecoration( image: DecorationImage( image: NetworkImage( headImageAssetPath), fit: BoxFit.cover), ), ), ), Padding( padding: const EdgeInsets.all(8.0), child: Align( alignment: FractionalOffset.topLeft, child: CircleAvatar( backgroundColor: Colors.redAccent, radius: 15.0, child: Text( noro, textScaleFactor: 0.5, ), ), ), ), Align( alignment: FractionalOffset.topRight, child: Container( color: Colors.blueAccent, height: 35.0, width: 35.0, child: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Icon(Icons.account_circle), Text( "1P", textScaleFactor: 0.5, ), ], ), ), ), ), ], ), ), Center( child: Container( padding: const EdgeInsets.all(8.0), alignment: FractionalOffset.bottomCenter, child: Text( title, style: TextStyle( fontWeight: FontWeight.w700, ), ), ), ), Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: <Widget>[ FlatButton( child: Text( "Add To Cart", style: TextStyle(color: Colors.grey[500]), ), onPressed: () => null, ), Text( "\$5", style: TextStyle(color: Colors.grey[500]), ) ], ) ], ), ), ], ); } } 

Actual App Screenshot:

0

6 Answers 6

41

This should work for one item

 body: new StreamBuilder( stream: Firestore.instance.collection("collection").snapshots(), builder: (context, snapshot) { if (!snapshot.hasData) { return Text( 'No Data...', ); } else { <DocumentSnapshot> items = snapshot.data.documents; return new Lost_Card( headImageAssetPath : items[0]["url"] ); } 

If you want to create list builder from many documents use it like this

 return new ListView.builder( itemCount: snapshot.data.documents.length, itemBuilder: (context, index) { DocumentSnapshot ds = snapshot.data.documents[index]; return new Lost_Card( headImageAssetPath : ds["url"]; ); 
Sign up to request clarification or add additional context in comments.

5 Comments

You saved the day!
wasted a day doing hit and trial before finding your answer. thanks a lot.. Now stuck at other bugs. XD Will fix them now.. : )
I want to prepare dataList List typed variable in a function which will be called in InitState function then I want to pass that dataList List typed variable to build function to show records of dataList List typed variable. Kindly share your suggestion. How can I do? Thanks.
for me, snapshot.data is of type Object?, so this does not work
@IceFire You might not be adding the type of StreamBuilder. Check this StreamBuilder<QuerySnapshot>
10

Accessing documents using StreamBuilder in Flutter 2

StreamBuilder<QuerySnapshot>( stream: FirebaseFirestore.instance.collection('products').snapshots(), builder: (context, snapshot) { if (snapshot.hasData) { return ListView.builder( itemCount: snapshot.data!.docs.length, itemBuilder: (context, index) { DocumentSnapshot doc = snapshot.data!.docs[index]; return Text(doc['name']); }); } else { return Text("No data"); } }, ) 

Comments

4

As per new changes 2021 in Firebase FireStore you can retrieve data from collection using StreamBuilder as below

final _mFirestore = FirebaseFirestore.instance; return StreamBuilder<QuerySnapshot>( stream: _mFirestore.collection(kFirebaseCollectionName).snapshots(), builder: (context, snapshots) { if (!snapshots.hasData) { return Center( child: Text('Data not available',), ); } final messages = snapshots.data.docs; List<Text> textWidgets = []; messages.forEach((element) { final messageText = element['text']; final messageSender = element['sender']; final textWidget = Text('$messageText, $messageSender'); textWidgets.add(messageBubbleWidget); }); }, ); 

Comments

1
Card buildItem(DocumentSnapshot doc) { return Card( child: Padding( padding: const EdgeInsets.all(8.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ Text( 'name: ${doc.data['name']}', style: TextStyle(fontSize: 24), ), Text( 'todo: ${doc.data['todo']}', style: TextStyle(fontSize: 20), ), Text( 'Age: ${doc.data['age']}', style: TextStyle(fontSize: 10), ), SizedBox( height: 12, ), ], ) ], ), ), ); } 

For other persons who will face the same problem, the card and stream builder will represent a solution. The Widget has the Card just before it declaration and has inside the body the next part:

 body: ListView( padding: EdgeInsets.all(8), children: <Widget>[ Form( key: _formKey, child: buildTextFormField(), ), StreamBuilder<QuerySnapshot>( stream: db .collection('CRUD') .snapshots(), builder: (context, snapshot) { if (snapshot.hasData) { return Column( children: snapshot.data.documents .map((doc) => buildItem(doc)) .toList()); } else { return SizedBox(); } }, ) ], ), 

Comments

1

Update for 2022, Flutter 2.10, cloud_firestore: ^3.1.11. You can retrieve data from collection using StreamBuilder

Stream collectionStream = FirebaseFirestore.instance.collection('users').snapshots(); StreamBuilder<QuerySnapshot>( builder: (context, snapshot) { if (snapshot.hasData) { final messages = snapshot.data!.docs; List<Text> messageWidgets = []; for (var element in messages) { final messageText = element['text']; final messageSender = element['sender']; final messageWidget = Text('$messageText from $messageSender'); messageWidgets.add(messageWidget); } return Column( children: messageWidgets, ); } return const Text('Error'); }, stream:collectionStream), 

Comments

0
StreamBuilder<List<UData>>( stream: AdminData().getDrivers, builder: (context, snapshot) { return ListView( children: snapshot.data.map((document) { return hadCard( widget: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ hadText(title: document.name), hadText(title: document.phone), hadText(title: document.Driver), ], ), ); }).toList(), ); }), 

1 Comment

I want to prepare dataList List typed variable in a function which will be called in InitState function then I want to pass that dataList List typed variable to build function to show records of dataList List typed variable. Kindly share your suggestion. How can I do? Thanks.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.