I'm currently trying to create a sliverlist that gets a list of user UID's from firebase then uses the streambuilder to find the information for each user. The problem is that is creates a bunch of sliverlists with a streambuilder listview inside so I have a bunch of items that are part of their own individual lists. How can I make this more efficiently to only build one sliverlist with all the item?
return SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
return StreamBuilder(
stream: userSearch(context, snapshot.data['members'][index]),
builder: (context, snapshot) {
return ListView.separated(
shrinkWrap: true,
padding: const EdgeInsets.all(8),
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
return userWidget(
context,
snapshot.data[index],
);
},
separatorBuilder: (BuildContext context, int index) =>
const Divider(),
);
},
);
},
childCount: snapshot.data['members'].length,
),
);
You can add NeverScrollableScrollPhysics() as the ScrollPhysics for the inner ListView.
It makes the ListView not scroll which means only the SliverList can scroll the items.
return ListView.separated(
physics: NeverScrollableScrollPhysics(), //Add this line
...
);
Related
I am looking to retrieve data stored in Firebase Realtime database and display it in a new page in a lisview, how can I achieve that. So far I can retrieve and print it out in a console terminal.
My code is below:
class BarcodesResultPreviewWidget extends StatelessWidget {
FirebaseDatabase.instance.reference().child('ScannedResults');
body: Column(
children: <Widget>[
previewView,
//printing scanned results
Expanded(
child: ListView.builder(
itemBuilder: (context, position) {
return BarcodeItemWidget(preview.barcodeItems[position]);
},
itemCount: preview.barcodeItems.length,
),
),
FlatButton(
color: Colors.grey,
child: Text('Save',),
onPressed: () {
databaseRef.push().set({
'ScannedItem': preview.barcodeItems
.map((barCodeItem) => barCodeItem.toJson())
.toString(),
});
},
),
To fetch the data into a new page and build listview, try something like this:
return Scaffold(
body: FutureBuilder(
future: databaseRef.once(),
// future: FirebaseDatabase.instance
// .reference()
// .child("ScannedResults")
// .once(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.waiting)
return new Text('Loading....');
if (snapshot.hasError) return new Text('Error: ${snapshot.error}');
List scannedItemsValues = [];
snapshot.data.value.forEach(
(_, values) => scannedItemsValues.add(values["ScannedItem"]));
print(scannedItemsValues);
return ListView.builder(
itemCount: scannedItemsValues.length,
itemBuilder: (BuildContext context, int index) {
// build your listView here
print(scannedItemsValues[index]);
return Text(scannedItemsValues[index]);
},
);
},
),
);
I am having a trouble reading collection from firebase and saving values in a list.
I basically have a collection called 'brands' where I have car brands like this:
Firebase 'brands' collection screenshot
I need these car brands to be saved as a list like this, to be able to use it in a dropdown menu as items:
<String>[
'ferrari',
'mercedes',
'porsche',
]
I have tried using StreamBuilder (below) but it requires to return a widget and I do not actually need a widget to be returned, so below StreamBuilder is just an experiment "in progress".
Do you have any ideas?
final stream = FirebaseFirestore.instance
.collection('accounts')
.doc('dealers')
.collection(user!.uid)
.doc(dealerName)
.collection('brands')
.snapshots();
StreamBuilder(
stream: stream,
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasError) {
return Text('Error in receiving snapshot: ${snapshot.error}');
}
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(
backgroundColor: Theme.of(context).primaryColor,
),
);
}
return ListView.builder(
padding: EdgeInsets.all(8),
reverse: true,
itemCount: snapshot.data.docs!.length,
itemBuilder: (BuildContext context, int index) {
return Text(
snapshot.data.docs[index]['brandName'],
);
},
);
},
);
Once you get the data from firebase, loop through it and add the car brands to your list. Try this:
List<String> myBrands = [];
final dataRef = await FirebaseFirestore.instance
.collection('accounts')
.doc('dealers')
.collection(user!.uid)
.doc(dealerName)
.collection('brands')
.get();
dataRef.docs.forEach((doc) {
myBrands.add(doc.data()['brandName']);
});
You should then be able to use the myBrands list for your dropdown menu.
i wanted my list of pageview containers to be created according to the number of documents in a collection in my cloud Firestore so that when clicked i can display data from each document on each page, is there a way to do this,thanks
You can use a StreamBuilder with a PageView.builder inside as the builder. For example, let Object be the type of the documents you are getting from Firestore:
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(8.0),
child: StreamBuilder<List<Object>>(
stream: firestoreService.getObjectsList, // something that returns an Object
builder: (context, snapshot) {
if (snapshot.data == null) {
return Center(child: CircularProgressIndicator());
} else {
return Scrollbar(
child: PageView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
// return something for each object in each page
}),
);
}
}),
));
}
This is my dataset :
I am trying to get this type of data in my app 1st I use an array and in the array i add map data and my value but i don't get any data.
My code
child: StreamBuilder(
stream: FirebaseFirestore.instance.collection("coin").snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Loder();
}
return ListView.builder(
itemCount: snapshot.data.document.length,
itemBuilder: (BuildContext context, int index) {
Map<dynamic, dynamic> map = snapshot.data.documents[index];
return ListTile(
title: Text(map.values.toList()[index]["coinlink"]),
);
},
);
}),
EDIT 1
I got this error I need data from coinlink title and img
The following NoSuchMethodError was thrown building StreamBuilder<QuerySnapshot<Map<String,
dynamic>>>(dirty, state: _StreamBuilderBaseState<QuerySnapshot<Map<String, dynamic>>,
AsyncSnapshot<QuerySnapshot<Map<String, dynamic>>>>#29591):
Class '_JsonQuerySnapshot' has no instance getter 'document'.
How to get this type of data?
You need column inside list of display multiple coinLinks.
return ListView.builder(
itemCount: snapshot.data.document.length,
itemBuilder: (BuildContext context, int index) {
Map<dynamic, dynamic> map = snapshot.data.documents[index];
final coinLinks = map["coinLink"] as List<Map<String,dynamic>>;
return ListTile(
title: Column(
children: coinLinks.map((coinLink){
return Text(coinLink["title"]);
}).toList()
),
);
},
);
I'm trying to add a header item at the beginning of my list, so here is how I build it using firebase
new Expanded(
child: new StreamBuilder(
stream: Firestore.instance
.collection("users")
.document("dana")
.collection("Channels")
.snapshots(),
builder: (context, snapshot) {
return new ListView.builder(
scrollDirection: Axis.vertical,
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) => _buildList(
context, snapshot.data.documents[index]),
);
}),
)
"_buildList" is just the Widget
Widget _buildListItem(BuildContext context, DocumentSnapshot document)
so I'm basically lost, I've no idea how to add another Widget as header
any suggestions?
You could return the "header" widget (the one you want above the listview but still in it) when the list is on index 0:
return new ListView.builder(
scrollDirection: Axis.vertical,
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) {
if (index == 0) {
return someWidget, // return the widget you want as "header" here
} else {
return _buildList( context, snapshot.data.documents[index-1]),
}
}
);