GridView.builder is not scrolling - firebase

I have this code and I am trying to make this gridview scrollable and no matter what I do it is not scrolling. I keep getting this renderoverflow error. I have tried to wrap it around SingleChildScroll view and also physics: ScrollPhysics() in its properties but nothing works. I just need to make this gridView scrollable and not the text below it. I have tried several ways but nothing as of now works for it. Might be a dumb mistake that I might be doing here but can't figure it out.
Edit: It works fine when I set singleChildScrollView after that body tag of scaffold but does not work when I apply it to GridView.
class _CartGridViewState extends State<CartGridView> {
#override
Widget build(BuildContext context) {
final User user = FirebaseAuth.instance.currentUser;
double sum = 0;
print(user);
return StreamBuilder(
stream: FirebaseFirestore.instance
.collection('Users')
.doc(user.uid)
.collection('Cart')
.snapshots(),
builder: (BuildContext context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
}
var document = snapshot.data.docs;
return Padding(
padding: const EdgeInsets.all(10.0),
child: SingleChildScrollView(
physics: ScrollPhysics(),
child: GridView.builder(
physics: ScrollPhysics(),
scrollDirection: Axis.vertical,
primary: false,
shrinkWrap: true,
itemCount: document.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: MediaQuery.of(context).size.height / 800,
),
itemBuilder: (context, index) {
if (document[index].data()["name"] == null) {
return Text('There are $index items in cart');
} else {
return Card(
child: GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CartView(
document[index].data()["name"],
document[index]
.data()["price"]
.toDouble(),
document[index].data()["image"],
index,
)),
);
},
child: Stack(children: [
ListView(physics: ScrollPhysics(), children: [
Hero(
tag: 'tagImage$index',
child: Image.network(
"${document[index].data()["image"]}",
height: 150,
),
),
Center(
child: Text(
"Price ${document[index].data()["price"]}")),
]),
DeleteCartItems(index),
]),
),
);
}
}),
),
);
},
);
}
}

We can make use of Expanded widget to get scrollable GridView
Please refer below code
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<String> images = [
"https://images.unsplash.com/photo-1614961234425-dedd96e5e699?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxleHBsb3JlLWZlZWR8M3x8fGVufDB8fHw%3D&auto=format&fit=crop&w=500&q=60",
"https://images.unsplash.com/photo-1614961234425-dedd96e5e699?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxleHBsb3JlLWZlZWR8M3x8fGVufDB8fHw%3D&auto=format&fit=crop&w=500&q=60",
"https://images.unsplash.com/photo-1614961234425-dedd96e5e699?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxleHBsb3JlLWZlZWR8M3x8fGVufDB8fHw%3D&auto=format&fit=crop&w=500&q=60",
"https://images.unsplash.com/photo-1614961234425-dedd96e5e699?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxleHBsb3JlLWZlZWR8M3x8fGVufDB8fHw%3D&auto=format&fit=crop&w=500&q=60",
"https://images.unsplash.com/photo-1614961234425-dedd96e5e699?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxleHBsb3JlLWZlZWR8M3x8fGVufDB8fHw%3D&auto=format&fit=crop&w=500&q=60",
"https://images.unsplash.com/photo-1614961234425-dedd96e5e699?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxleHBsb3JlLWZlZWR8M3x8fGVufDB8fHw%3D&auto=format&fit=crop&w=500&q=60",
"https://images.unsplash.com/photo-1614961234425-dedd96e5e699?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxleHBsb3JlLWZlZWR8M3x8fGVufDB8fHw%3D&auto=format&fit=crop&w=500&q=60",
"https://images.unsplash.com/photo-1614961234425-dedd96e5e699?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxleHBsb3JlLWZlZWR8M3x8fGVufDB8fHw%3D&auto=format&fit=crop&w=500&q=60",
"https://images.unsplash.com/photo-1614961234425-dedd96e5e699?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxleHBsb3JlLWZlZWR8M3x8fGVufDB8fHw%3D&auto=format&fit=crop&w=500&q=60",
"https://images.unsplash.com/photo-1614961234425-dedd96e5e699?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxleHBsb3JlLWZlZWR8M3x8fGVufDB8fHw%3D&auto=format&fit=crop&w=500&q=60",
"https://images.unsplash.com/photo-1614961234425-dedd96e5e699?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxleHBsb3JlLWZlZWR8M3x8fGVufDB8fHw%3D&auto=format&fit=crop&w=500&q=60",
"https://images.unsplash.com/photo-1614961234425-dedd96e5e699?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxleHBsb3JlLWZlZWR8M3x8fGVufDB8fHw%3D&auto=format&fit=crop&w=500&q=60",
];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Padding(
padding: EdgeInsets.symmetric(
horizontal: 12.0,
),
child: Expanded(
child: GridView.builder(
itemCount: images.length,
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 8.0,
mainAxisSpacing: 10.0),
itemBuilder: (BuildContext context, int index) {
return Image.network(images[index]);
},
),
),
),
);
}
}

Related

my value becomes null in streambuilder listview.builder when getting data from firebase

I see that the stream builder returns ${globals.statusKey} as null, but I don't know why, because I can print the value out well, and the FriendStatus code is also a widget that I called well in another part of the app(which was drawer).
I can see these kinds of problem occurring frequently in stream builder but cannot find any solution.
There is an error like below
'package:cloud_firestore/src/firestore.dart': Failed assertion: line 63 ps 7:1 '! collectionPath.contains('//'):a collection path must not contain "//"
And here is the code.
body: SafeArea(
child: Container(
padding: EdgeInsets.fromLTRB(10, 5, 0, 0),
// child: SingleChildScrollView(
// scrollDirection: Axis.vertical,
child: Column(children: [
tapableDate(),
const SizedBox(
height: 10,
),
Container(
height: 220,
width: 330,
decoration: BoxDecoration(
border: Border.all(
color: Colors.black,
),
),
child: FriendStatus(),
),
Text(
"See \n statusKey: ${globals.statusKey} \n count: \n",
),
// Provider(create: (context) => TimerService(), child: EventList()),
// ),
]),
// ),
),
),
Code of FriendStatus.dart
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:gw/globals.dart' as globals;
class FriendStatus extends StatefulWidget {
const FriendStatus({Key? key}) : super(key: key);
#override
State<FriendStatus> createState() => _FriendStatusState();
}
class _FriendStatusState extends State<FriendStatus> {
FirebaseFirestore firestore = FirebaseFirestore.instance;
#override
Widget build(BuildContext context) {
return Expanded(
child: Container(
padding: EdgeInsets.fromLTRB(20, 10, 20, 0),
child: Column(
children: [
StreamBuilder(
stream: FirebaseFirestore.instance
.collection('user/${globals.currentUid}/friends')
.snapshots(),
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot<Map<String, dynamic>>>
snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
);
}
final docs = snapshot.data!.docs;
return ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: docs.length,
itemBuilder: (context, index) {
return Container(
//padding:,
child: ListTile(
leading: Icon(
Icons.circle,
color: Colors.grey[850],
),
title: Text(docs[index]['name']),
));
},
);
},
)
],
)),
);
}
}

Error: The argument type 'Stream<PostsRecord>' can't be assigned to the parameter type 'Record'

New to flutter here (and coding in general) but have an issue that I cannot figure out to solve. I am navigating to a page based off of a variable and need to pass in a Record. However, I cannot figure out how to pass a Record from the reference already on the page (postReference). I only want to read this document if the button is pressed also. Using Firebase/Firestore as the backend. Any help is greatly appreciated!
Error
Error: The argument type 'Stream' can't be assigned to the parameter type 'PostsRecord'.
Code snippet below. I cannot figure out how to properly query the record to then pass to the Widget Builder.
class NotificationPageWidget extends StatefulWidget {
const NotificationPageWidget({Key key}) : super(key: key);
#override
_NotificationPageWidgetState createState() => _NotificationPageWidgetState();
}
class _NotificationPageWidgetState extends State<NotificationPageWidget> {
final scaffoldKey = GlobalKey<ScaffoldState>();
#override
Widget build(BuildContext context) {
return Scaffold(
key: scaffoldKey,
appBar: AppBar(
automaticallyImplyLeading: true,
title: Text(
'Notifications',
style: FlutterFlowTheme.title1,
),
),
body: SafeArea(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
child: StreamBuilder<List<UserNotificationsRecord>>(
stream: queryUserNotificationsRecord(
queryBuilder: (userNotificationsRecord) =>
userNotificationsRecord
.where('notifiedUsers',
arrayContains: currentUserReference)
.orderBy('notificationTime', descending: true),
),
builder: (context, snapshot) {
// Customize what your widget looks like when it's loading.
if (!snapshot.hasData) {
return Center(
child: SizedBox(
width: 40,
height: 40,
child: CircularProgressIndicator(
color: FlutterFlowTheme.secondaryColor,
),
),
);
}
List<UserNotificationsRecord>
listViewUserNotificationsRecordList = snapshot.data;
return ListView.builder(
padding: EdgeInsets.zero,
scrollDirection: Axis.vertical,
itemCount: listViewUserNotificationsRecordList.length,
itemBuilder: (context, listViewIndex) {
final listViewUserNotificationsRecord =
listViewUserNotificationsRecordList[listViewIndex];
return InkWell(
onTap: () {
if (listViewUserNotificationsRecord.initialPageName == '/commentsPage') {
final postRef = PostsRecord.getDocument(listViewUserNotificationsRecord.postReference);
Navigator.push(context, MaterialPageRoute(builder: (context) => CommentsPageWidget(
activityRecord: postRef,
//This is where the error is occurring. Looking for a Record and not a Reference.
)
)
);
};
},
);
},
);
},
),
),
],
),
),
);
}
}

Could someone tell me how to turn this into a listview.builder and still have it connected to firebase? btw the name of my collection is 'groceries'

Currently it is a listview, I know how to normally create a listview.builder but I don't know how to connect it to firebase. Im talking about the streambuilder and context and all that stuff. Really appreciate any help, Im new to flutter so sorry if this is an obvious/dumb question.
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(FireApp());
}
class FireApp extends StatefulWidget {
#override
_FireAppState createState() => _FireAppState();
}
class _FireAppState extends State<FireApp> {
final TextController = TextEditingController();
bool isChecked = false;
#override
Widget build(BuildContext context) {
CollectionReference groceries =
FirebaseFirestore.instance.collection('groceries');
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: TextField(
controller: TextController,
),
),
body: Center(
child: StreamBuilder(
stream: groceries.orderBy('name').snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
return ListView(
children: snapshot.data!.docs.map((grocery) {
return Center(
child: Row(
children: [
Container(color: Colors.red,height: 50,child: Text(grocery['name'])),
Checkbox(
materialTapTargetSize: MaterialTapTargetSize.padded,
value: isChecked,
activeColor: Colors.black,
checkColor: Colors.greenAccent,
onChanged: (bool) {
setState(() {
isChecked = !isChecked;
});
}
)],
),
);
}).toList(),
);
},
),
),
floatingActionButton: FloatingActionButton(onPressed: () {
groceries.add({
'name': TextController.text,
});
},),
),
);
}
}
StreamBuilder and listview.builder sample code given below
StreamBuilder<QuerySnapshot<Map<String, dynamic>>>(
stream: groceries.orderBy('name').snapshots(),
builder: (context,
AsyncSnapshot<QuerySnapshot<Map<String, dynamic>>> snapshot) {
// your list of groceries
List groceriesList =
snapshot.data.docs.map((e) => e.data()).toList();
return ListView.builder(
itemCount: groceriesList.length,
itemBuilder: (context, i) {
// build your widget here.
return Center(
child: Row(
children: [
Container(
color: Colors.red,
height: 50,
child: Text(groceriesList[i]['name']),
),
Checkbox(
materialTapTargetSize: MaterialTapTargetSize.padded,
value: isChecked,
activeColor: Colors.black,
checkColor: Colors.greenAccent,
onChanged: (bool) {
setState(() => isChecked = !isChecked);
},
)
],
),
);
},
);
},
),

Retrieve array from Firebase in Flutter

I want to retrieve array from firebase or cloud_firestore.
I have no problem with retrieving single data but i am having problem with retrieving array data
please help my beginner mind is at the verge of exploding.
I have google it and gone through many tutorials videos but i can't find the solution
database image here
pubspec.yaml
dependencies:
cloud_firestore: ^0.13.6
main.dart
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: Scaffold(
appBar: AppBar(title: Text("Flutter Fire CRUD")),
body: ListPage(),
),
);
}
}
class ListPage extends StatefulWidget {
#override
_ListPageState createState() => _ListPageState();
}
class _ListPageState extends State<ListPage> {
Future _data;
Future getUsers() async {
var firestore = Firestore.instance;
firestore.collection("users").getDocuments();
QuerySnapshot qn = await firestore.collection("users").getDocuments();
return qn.documents;
}
navigateToDetail(DocumentSnapshot users) {
Navigator.push(context,
MaterialPageRoute(builder: (context) => DetailList(users: users)));
}
#override
void initState() {
super.initState();
_data = getUsers();
}
#override
Widget build(BuildContext context) {
return Container(
child: FutureBuilder(
future: _data,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Text("Loading ...");
} else {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(snapshot.data[index].data['name']),
onTap: () {
navigateToDetail(snapshot.data[index]);
});
},
);
}
},
),
);
}
}
class DetailList extends StatefulWidget {
final DocumentSnapshot users;
DetailList({Key key, #required this.users}) : super(key: key);
#override
_DetailListState createState() => _DetailListState();
}
class _DetailListState extends State<DetailList> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("${widget.users.data['name']}"),
),
body: Column(
children: [
Container(
height: MediaQuery.of(context).size.height / 2.0,
width: MediaQuery.of(context).size.width,
child: Center(
child: Image.network(widget.users.data["img"]),
),
),
Container(
child: Card(
child: ListTile(
title: Text(widget.users.data["name"]),
subtitle: Text("Age:" + widget.users.data["age"]),
),
),
),
ListView.builder(
itemCount: widget.users.data["skills"],
itemBuilder: (context, index) {
return ListTile(
//title: Text(widget.users.data["skills"][index]),
title: here............
);
},
)
],
),
);
}
}
StreamBuilder(
stream: Firestore.instance
.collection('users')
.document(id)
.collection('chatWith')
.orderBy('timestamp', descending: true)
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(
AppColor.colorCustom),
),
);
} else {
if (snapshot.data.documents.length == 0) {
return Container(
alignment: Alignment.center,
child: Text(
"No Chat History Found",
style: TextStyle(
color: Colors.grey,
fontWeight: FontWeight.normal,
fontSize:
Util.px_23 * SizeConfig.textMultiplier,
fontFamily: 'Roboto',
),
softWrap: true,
),
);
} else {
return ListView.builder(
padding: EdgeInsets.all(
Util.px_10 * SizeConfig.heightMultiplier),
itemBuilder: (context, index) => _listItem(
context, snapshot.data.documents[index]),
itemCount: snapshot.data.documents.length,
);
}
}
},
)
You can fetch list of data from firestore. this code I have used in my project. You can modify as per your requirement.

Flutter - Filter out the display items according to Firebase keys, and in descending order

I am trying to create a Flutter portfolio sorted by "categories" with flat buttons. When one click on the categories, the related projects will be filtered and displayed accordingly, in descending order based on the timestamp.
I have succeeded in displaying the projects in descending order, however have been unable to display my projects by the key value.
Code for the "categories" flat buttons:
class PortfolioCategories extends StatefulWidget {
#override
_PortfolioCategoriesState createState() => new _PortfolioCategoriesState();
}
class _PortfolioCategoriesState extends State<PortfolioCategories> {
void _select(CategoryChoice category) {
setState(() {
PortfolioRow.itemBuilder(context, category.categoryIndex);
});
}
class CategoryChoice {
const CategoryChoice({this.category, this.categoryIndex});
final String category;
final String categoryIndex; //value of 'category' key in Firebase
}
const List<CategoryChoice> categories = const <CategoryChoice>[
const CategoryChoice(category: 'ALL', categoryIndex: 'Category_ALL'),
const CategoryChoice(
category: 'MULTIMEDIA DESIGN', categoryIndex: 'Category_1'),
const CategoryChoice(category: 'CURATORIAL', categoryIndex: 'Category_2'),
const CategoryChoice(category: 'ART', categoryIndex: 'Category_3'),
];
Code for my portfolio:
class PortfolioRow extends StatelessWidget {
const PortfolioRow({Key key, this.category}) : super(key: key);
final CategoryChoice category;
#override
Widget build(BuildContext context) {
return StreamBuilder(
stream: Firestore.instance
.collection('portfolio')
.orderBy('createdAt', descending: true)
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) return Text("Loading...");
return GridView.builder(
physics: ScrollPhysics(),
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
),
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) =>
portfolioContainer(context, snapshot.data.documents[index])); //portfolioContainer is the portfolio projects that will be displayed
},
);
}
}
My question could be answered by this: how to use where with orderby in flutter
And then with:
.where('category', arrayContainsAny:[category.categoryName]) .orderBy('createdAt', descending: true)
Regarding the query, I was silly to have tried to allow variables query from different classes. I succeed to query request from FlatButton to portfolioRow() when all the code were all appended as a child in _portfolioCategoriesState() as below:
class PortfolioCategoriesAndDisplay extends StatefulWidget {
#override
_PortfolioCategoriesAndDisplayState createState() =>
new _PortfolioCategoriesAndDisplayState();
}
String _showCat = 'All'; //default state is All
class CategoryChoice {
const CategoryChoice({this.category, this.categoryName});
final String category;
final String categoryName; //'category.[Name]' in Firebase
#override
String toString() {
return 'category: $category categoryName: $categoryName';
}
}
const List<CategoryChoice> categories = const <CategoryChoice>[
const CategoryChoice(categoryName: 'All'),
const CategoryChoice(categoryName: 'Multimedia Design'),
const CategoryChoice(categoryName: 'Curatorial'),
const CategoryChoice(categoryName: 'Sustainability'),
];
class _PortfolioCategoriesAndDisplayState
extends State<PortfolioCategoriesAndDisplay> {
void _select(String newCategory) {
setState(() {
_showCat = newCategory;
});
}
Widget build(BuildContext context) {
return Container(
child: Row(
children: [
Expanded(
child:
Column(children: [
Container(
child:
Row(children: [
FlatButton(
onPressed: () {
_select(categories[0].categoryName);
},
child: Text(
'ALL',
)),
FlatButton(
onPressed: () {
_select(categories[1].categoryName);
},
child: Text(
'MULTIMEDIA DESIGN',
)),
FlatButton(
onPressed: () {
_select(categories[2].categoryName);
},
child: Text(
'CURATORIAL',
)),
FlatButton(
onPressed: () {
_select(categories[3].categoryName);
},
child: Text(
'SUSTAINABILITY',
)),
]),
),
StreamBuilder(
stream: Firestore.instance
.collection('portfolio')
.where('category', arrayContainsAny: [_showCat])
.orderBy('projectOrder', descending: true)
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) return Text("Loading...");
return GridView.builder(
physics: ScrollPhysics(),
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 70.0,
mainAxisSpacing: 70.0,
childAspectRatio:
MediaQuery.of(context).size.height / 1280,
),
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) => portfolioContainer(
context, snapshot.data.documents[index]));
},
)
]),
)
],
));
}
}

Resources