error:- Another exception was thrown: A RenderFlex overflowed by 33 pixels on the bottom - firebase

[enter image description here]
1Error showing when i run my app...My code is below ...can anyone tell what is wrong with my code
///////////////////////
Error showing when i run my app...My code is below ...can anyone tell what is wrong with my code
///////////////////////
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'dart:async';
import
'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
class OfferPage extends StatefulWidget {
#override
_OfferPageState createState() => new _OfferPageState();
}
class _OfferPageState extends State<OfferPage> {
StreamSubscription<QuerySnapshot> subscription;
List<DocumentSnapshot> offerpostList;
final CollectionReference collectionReference =
Firestore.instance.collection("todos");
#override
void initState() {
// TODO: implement initState
super.initState();
subscription = collectionReference.snapshots().listen((datasnapshot) {
setState(() {
offerpostList = datasnapshot.documents;
});
});
// _currentScreen();
}
#override
void dispose() {
subscription?.cancel();
super.dispose();
}
#override
Widget build(BuildContext context) {
return new Scaffold(
body: offerpostList != null? new StaggeredGridView.countBuilder(
padding: const EdgeInsets.all(8.0),
crossAxisCount: 4,
itemCount: offerpostList.length,
itemBuilder: (context, i) {
String imgPath = offerpostList[i].data['url'];
String title = offerpostList[i].data['productTitle'];
return new Material(
elevation: 8.0,
borderRadius:
new BorderRadius.all(new Radius.circular(8.0)),
child: new InkWell(
child:new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(title,style: new TextStyle(
fontStyle: FontStyle.italic,
color: Colors.green[900],
fontSize: 16.0)),
new Hero(
tag: imgPath,
child:
new FadeInImage(
image: new NetworkImage(imgPath),
fit: BoxFit.cover,
placeholder: new AssetImage("assets/logo.png"),
),
),
],
),
),
);
},
staggeredTileBuilder: (i) =>
new StaggeredTile.count(2, i.isEven ? 2 : 3),
mainAxisSpacing: 8.0,
crossAxisSpacing: 8.0,
)
: new Center(
child: new CircularProgressIndicator(),
));
}
}

Column in flutter doesn't have scrolling ability. The issue is your data from firebase cannot be fit inside a single screen. That's why overflow error was thrown. Use ListView instead of Column which has the scrolling ability.

Column widget for available room in the device to get qll data in firebase and also to get scroll effect you can use FirebaseAnimatedList.

For an Olx like gridview with text over image, here is a sample. Try it out and change your question because it might be misleading.
main.dart
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firestore_grid_view/product.dart';
import 'package:firestore_grid_view/product_details.dart';
import 'package:flutter/material.dart';
void main() => runApp(new MaterialApp(
home: new MyApp(),
debugShowCheckedModeBanner: false,
));
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
List<Product> _products = [];
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Home'),
),
body: new StreamBuilder<QuerySnapshot>(
stream: Firestore.instance.collection('products').snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) return new Text('Loading...');
return new GridView.count(
crossAxisCount: 2,
children: _buildGrid(snapshot.data.documents),
);
},
),
);
}
List<Widget> _buildGrid(List<DocumentSnapshot> documents) {
List<Widget> _gridItems = [];
_products.clear();
for (DocumentSnapshot document in documents) {
_products.add(new Product(
name: document['productTitle'],
category: document['category'],
imageUrl: document['url'],
contactNumber: document['contactNumber']));
}
for (Product product in _products) {
_gridItems.add(_buildGridItem(product));
}
return _gridItems;
}
Widget _buildGridItem(Product product) {
return new GestureDetector(
child: new Card(
child: new Stack(
alignment: Alignment.center,
children: <Widget>[
new Hero(
tag: product.name,
child: new Image.network(product.imageUrl, fit: BoxFit.cover),
),
new Align(
child: new Container(
padding: const EdgeInsets.all(10.0),
child: new Text(product.name,
style: new TextStyle(color: Colors.white)),
color: Colors.black.withOpacity(0.4),
width: double.infinity,
),
alignment: Alignment.bottomCenter,
),
],
),
),
onTap: () => onProductTapped(product),
);
}
onProductTapped(Product product) {
Navigator.of(context).push(new MaterialPageRoute(
builder: (context) => new ProductDetails(product)));
}
}
product_details.dart
import 'package:firestore_grid_view/product.dart';
import 'package:flutter/material.dart';
class ProductDetails extends StatelessWidget {
final Product product;
ProductDetails(this.product);
#override
Widget build(BuildContext context) {
return new Scaffold(
body: new Column(
children: <Widget>[
new Expanded(child: new Container()),
new Hero(
tag: product.name,
child: new Image(
image: new NetworkImage(product.imageUrl),
fit: BoxFit.fill,
width: double.infinity,
height: 300.0,
)),
new Padding(
padding: const EdgeInsets.all(15.0),
child: new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Padding(
padding: const EdgeInsets.only(right: 8.0),
child: new Text(
'Category -',
style: new TextStyle(
fontSize: 20.0, fontWeight: FontWeight.bold),
),
),
new Text(
product.category,
style: new TextStyle(
fontSize: 20.0, fontWeight: FontWeight.bold),
),
],
),
),
new Padding(
padding: const EdgeInsets.symmetric(horizontal: 15.0),
child: new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Padding(
padding: const EdgeInsets.only(right: 8.0),
child: new Text(
'Contact Number -',
style: new TextStyle(
fontSize: 20.0, fontWeight: FontWeight.bold),
),
),
new Text(
product.contactNumber,
style: new TextStyle(
fontSize: 20.0, fontWeight: FontWeight.bold),
),
],
),
),
new Expanded(child: new Container()),
],
),
);
}
}
product.dart
class Product {
final name, category, imageUrl, contactNumber;
Product({this.name, this.category, this.imageUrl, this.contactNumber});
}

Related

Cant Figure Out How To display Only the post details for the post I have clicked on

So I have this code here and I would like to display post details from firebase for the post which I have clicked on, but instead, it lists post details for every single post in the database one after another.
Can anyone help me figure out how I can make it so that when A post is clicked, details will show for only the post which was clicked, and not for all of the posts? Any help would be greatly appreciated, thank you.
The Info I would like to display on the post is
postTitle
postDesc
postAuthor
Here is what the firebase looks like
Code Here:
import 'package:tennis_event_app/services/crud.dart';
import 'package:tennis_event_app/views/create_blog.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
CrudMethods crudMethods = new CrudMethods();
QuerySnapshot? blogSnapshot;
#override
void initState() {
crudMethods.getData()?.then((result) {
blogSnapshot = result;
setState(() {});
});
super.initState();
}
Widget blogsList() {
return Container(
child: ListView.builder(
padding: EdgeInsets.only(top: 24),
itemCount: blogSnapshot!.docs.length,
itemBuilder: (context, index) {
return BlogTile(
author: blogSnapshot!.docs[index].get('author'),
title: blogSnapshot!.docs[index].get('title'),
desc: blogSnapshot!.docs[index].get('desc'),
imgUrl: blogSnapshot!.docs[index].get('imgUrl'),
);
},
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
"Flutter",
style: TextStyle(fontSize: 22),
),
Text(
"Blog",
style: TextStyle(fontSize: 22, color: Colors.blue),
)
],
),
backgroundColor: Colors.transparent,
elevation: 0.0,
),
body: Container(
child: blogSnapshot != null
? blogsList()
: Container(
child: Center(
child: CircularProgressIndicator(),
))),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => CreateBlog()));
},
),
);
}
}
class BlogTile extends StatelessWidget {
final String imgUrl, title, desc, author;
BlogTile(
{required this.author,
required this.desc,
required this.imgUrl,
required this.title});
#override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.only(bottom: 16, right: 16, left: 16),
child: Stack(
children: <Widget>[
Container(
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(8)),
child: Image.network(
imgUrl,
width: MediaQuery.of(context).size.width,
fit: BoxFit.cover,
height: 170,
),
),
),
Container(
height: 170,
decoration: BoxDecoration(
color: Colors.black45.withOpacity(0.3),
borderRadius: BorderRadius.circular(6)),
),
Container(
height: 170,
width: MediaQuery.of(context).size.width,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
title,
textAlign: TextAlign.center,
style: TextStyle(fontSize: 25, fontWeight: FontWeight.w500),
),
SizedBox(height: 4),
Text(
'$desc',
style: TextStyle(fontSize: 17, fontWeight: FontWeight.w400),
),
SizedBox(
height: 4,
),
Text(author),
],
)),
Container(
child: SizedBox(
height: 170,
width: MediaQuery.of(context).size.width,
child: TextButton(
style: TextButton.styleFrom(
textStyle: const TextStyle(fontSize: 20),
),
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => DetailPage()));
},
child: const Text(''),
),
),
),
],
),
);
}
}
class DetailPage extends StatefulWidget {
#override
_DetailPageState createState() => _DetailPageState();
}
class _DetailPageState extends State<DetailPage> {
CrudMethods crudMethods = new CrudMethods();
QuerySnapshot? blogSnapshot;
#override
void initState() {
crudMethods.getData()?.then((result) {
blogSnapshot = result;
setState(() {});
});
super.initState();
}
Widget blogsList2() {
return Container(
child: ListView.builder(
padding: EdgeInsets.only(top: 24),
itemCount: blogSnapshot!.docs.length,
itemBuilder: (context, index) {
return PageContent(
postAuthor: blogSnapshot!.docs[index].get('postAuthor'),
postTitle: blogSnapshot!.docs[index].get('postTitle'),
postDesc: blogSnapshot!.docs[index].get('postDesc'),
imgUrl: blogSnapshot!.docs[index].get('imgUrl'),
);
},
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
"Flutter",
style: TextStyle(fontSize: 22),
),
Text(
"Blog",
style: TextStyle(fontSize: 22, color: Colors.blue),
)
],
),
backgroundColor: Colors.transparent,
elevation: 0.0,
),
body: Container(
child: blogSnapshot != null
? blogsList2()
: Container(
child: Center(
child: CircularProgressIndicator(),
))),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => CreateBlog()));
},
),
);
}
}
class PageContent extends StatelessWidget {
final String imgUrl, postTitle, postDesc, postAuthor;
PageContent(
{required this.postAuthor,
required this.postDesc,
required this.imgUrl,
required this.postTitle});
#override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.only(bottom: 16, right: 16, left: 16),
child: Card(
child: ListTile(
title: Text(
postTitle,
textAlign: TextAlign.center,
style: TextStyle(fontSize: 25, fontWeight: FontWeight.w500),
),
subtitle: Text(
'$postDesc',
style: TextStyle(fontSize: 17, fontWeight: FontWeight.w400),
),
)
)
);
}
}
I also reference crud.dart in that code, so incase you need it, here it is:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'dart:collection';
class CrudMethods {
Future<void> addData(blogData) async {
print(blogData);
FirebaseFirestore.instance
.collection("blogs")
.add(blogData)
.then((value) => print(value))
.catchError((e) {
print(e);
});
}
getData() async {
return await FirebaseFirestore.instance
.collection("blogs")
.orderBy("ts", descending: true)
.get();
}
}
Thank you again for any help!
First I would recommend to modelize your data in an object for exemple a class Article that is easier to serialize and manipulate.
Then instead of requesting another time the database you should save your data in a List<Article> for example then you only update this list on refresh from your main page. That way you don'y manipulate a QuerySnapshot or Future but just your list of objects.
Finally and to answer your question, you could simply pass the clicked item Article to your details page and only display its content. Because here, you have the same construction as your main page with the same request that is resent.
Usually you can build your route like that (adding a parameter to your details with the index you clicked on for example)
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => DetailPage(article: _data[i])));
},
Here is an article on serialization from Flutter docs, it shows how to build your model with the toMap, toJson and fromJson methods.

I cannot retrieve and view data from Firestore Flutter

#HOME: this is home linked to FeatureProducts()
And I cannot retrieve data "product", it always return nil.
I want to retrieve data from Firebase into the Listview.
this is my firebase cloud fire store Image of Firebase Database
i try many time with many ways and all codes doesn't give any errors, but When i run the app and open the activity the data cannot show they will be empty,
import 'package:farmers_ecommerce/commons/common.dart';
import 'package:farmers_ecommerce/db/product.dart';
import 'package:farmers_ecommerce/pages/product_search.dart';
import 'package:farmers_ecommerce/provider/product.dart';
import 'package:farmers_ecommerce/provider/user_provider.dart';
import 'package:farmers_ecommerce/widget/featured_products.dart';
import 'package:farmers_ecommerce/widget/product_card.dart';
import 'package:farmers_ecommerce/widgets/custom_text.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'cart.dart';
import 'order.dart';
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final _key = GlobalKey<ScaffoldState>();
ProductServices _productServices = ProductServices();
#override
Widget build(BuildContext context) {
final userProvider = Provider.of<UserProvider>(context);
final productProvider = Provider.of<ProductProvider>(context);
return Scaffold(
key: _key,
backgroundColor: Colors.white,
endDrawer: Drawer(
child: ListView(
children: <Widget>[
UserAccountsDrawerHeader(
decoration: BoxDecoration(color: Colors.black),
accountName: CustomText(
text: userProvider.userModel?.name ?? "username lading...",
color: Colors.white,
weight: FontWeight.bold,
size: 18,
),
accountEmail: CustomText(
text: userProvider.userModel?.email ?? "email loading...",
color: Colors.white,
),
),
ListTile(
onTap: () async{
await userProvider.getOrders();
changeScreen(context, OrdersScreen());
},
leading: Icon(Icons.bookmark_border),
title: CustomText(text: "My orders"),
),
ListTile(
onTap: () async{
userProvider.signOut();
},
leading: Icon(Icons.exit_to_app),
title: CustomText(text: "Log out"),
),
],
),
),
body: SafeArea(
child: ListView(
children: <Widget>[
// Custom App bar
Stack(
children: <Widget>[
Positioned(
top: 10,
right: 20,
child: Align(
alignment: Alignment.topRight,
child: GestureDetector(
onTap: () {
_key.currentState.openEndDrawer();
},
child: Icon(Icons.menu))),
),
Positioned(
top: 10,
right: 60,
child: Align(
alignment: Alignment.topRight,
child: GestureDetector(
onTap: (){
changeScreen(context, CartScreen());
},
child: Icon(Icons.shopping_cart))),
),
Positioned(
top: 10,
right: 100,
child: Align(
alignment: Alignment.topRight, child: GestureDetector(
onTap: (){
_key.currentState.showSnackBar(SnackBar(
content: Text("User profile")));
},
child: Icon(Icons.person))),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'What are\nyou Shopping for?',
style: TextStyle(
fontSize: 30,
color: Colors.black.withOpacity(0.6),
fontWeight: FontWeight.w400),
),
),
],
),
// Search Text field
// Search(),
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(20),
bottomLeft: Radius.circular(20))),
child: Padding(
padding: const EdgeInsets.only(
top: 8, left: 8, right: 8, bottom: 10),
child: Container(
decoration: BoxDecoration(
color: Colors.grey.withOpacity(0.2),
borderRadius: BorderRadius.circular(20),
),
child: ListTile(
leading: Icon(
Icons.search,
color: Colors.black,
),
title: TextField(
textInputAction: TextInputAction.search,
onSubmitted: (pattern)async{
await productProvider.search(productName: pattern);
changeScreen(context, ProductSearchScreen());
},
decoration: InputDecoration(
hintText: "fashion....",
border: InputBorder.none,
),
),
),
),
),
),
// featured products
Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(14.0),
child: Container(
alignment: Alignment.centerLeft,
child: new Text('Featured products')),
),
],
),
FeaturedProducts(),
**this is the feature products. i cannot see any thing on here.
its blank**
// recent products
Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(14.0),
child: Container(
alignment: Alignment.centerLeft,
child: new Text('Recent products')),
),
],
),
Column(
children: productProvider.products
.map((item) => GestureDetector(
child: ProductCard(
product: item,
),
))
.toList(),
)
],
),
),
);
}
}
#FEATURED PRODUCT: this is linked to ProductProvider which listens from the
database
import 'package:farmers_ecommerce/provider/product.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'featured_card.dart';
class FeaturedProducts extends StatefulWidget {
#override
_FeaturedProductsState createState() => _FeaturedProductsState();
}
class _FeaturedProductsState extends State<FeaturedProducts> {
#override
Widget build(BuildContext context) {
final productProvider = Provider.of<ProductProvider>(context);
return Container(
height: 230,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: productProvider.products.length,
itemBuilder: (_, index) {
return FeaturedCard(
product: productProvider.products[index],
);
}));
}
}
#PRODUCT PROVIDER
//i feel the provider is not loading any products
import 'package:farmers_ecommerce/db/product.dart';
import 'package:farmers_ecommerce/models/product.dart';
import 'package:flutter/material.dart';
class ProductProvider with ChangeNotifier{
ProductServices _productServices = ProductServices();
List<ProductModel> products = [];
List<ProductModel> productsSearched = [];
ProductProvider.initialize(){
loadProducts();
}
loadProducts()async{enter code here
products = await _productServices.getProducts();
notifyListeners();
}
Future search({String productName})async{
productsSearched = await _productServices.searchProducts(productName: productName);
notifyListeners();
}
}
//DATABASE TO FIRESTORE
//I tried using stream builder but it is not working using Future.
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:farmers_ecommerce/models/product.dart';
class ProductServices {
String collection = "products";
FirebaseFirestore _firestore = FirebaseFirestore.instance;
Future<List<ProductModel>> getProducts() async =>
_firestore.collection(collection).get().then((result) {
List<ProductModel> products = [];
for (DocumentSnapshot product in result.docs) {
products.add(ProductModel.fromSnapshot(product));
}
return products;
});
Future<List<ProductModel>> searchProducts({String productName}) {
// code to convert the first character to uppercase
String searchKey = productName[0].toUpperCase() + productName.substring(1);
return _firestore
.collection(collection). //return fire base
.orderBy("name")
.startAt([searchKey])
.endAt([searchKey + '\uf8ff'])
.get()
.then((result) {
List<ProductModel> products = [];
for (DocumentSnapshot product in result.docs) {
products.add(ProductModel.fromSnapshot(product));
}
return products;
});
}
}
In your ProductServices change this function:
Future<List<ProductModel>> getProducts() async {
QuerySnapshot result= await _firestore.collection(collection).get();
List<ProductModel> products = [];
for (DocumentSnapshot product in result.docs) {
products.add(ProductModel.fromSnapshot(product));
}
return products;
}
If you use then the return will be called when the code flow already left the function. To avoid that you need to await the result.

The following RangeError was thrown building Builder(dirty):

Context:
I'm trying to create a Dynamic Slider with Flutter, it'll get Firebase url's for the images that form a comic and put it into a CarouselSlider, I treated null and empty return's but it keep's displaying errors from invalid index in my app.
Error:
════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following RangeError was thrown building Builder(dirty):
RangeError (index): Invalid value: Valid value range is empty: 0
The relevant error-causing widget was:
Builder file:///Users/murilopazzini/Documents/Projs/SchoolsOut_Dev/schools_out/lib/components/hqSlider.dart:55:24
When the exception was thrown, this was the stack:
#0 List.[] (dart:core-patch/growable_array.dart:149:60)
#1 _hqSliderState.build.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:schools_out/components/hqSlider.dart:72:61)
#2 Builder.build (package:flutter/src/widgets/basic.dart:6757:41)
#3 StatelessElement.build (package:flutter/src/widgets/framework.dart:4291:28)
#4 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4223:15)
...
════════════════════════════════════════════════════════════════════════════════════════════════════
Home.dart
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:schools_out/pages/comicsPage.dart';
import 'package:schools_out/components/hqSlider.dart';
import 'package:schools_out/entities/comics.dart';
import 'package:schools_out/entities/comicsPage.dart';
class Homepage extends StatefulWidget {
#override
_HomepageState createState() => _HomepageState();
}
class _HomepageState extends State<Homepage>
with SingleTickerProviderStateMixin {
Animation animation;
AnimationController animationController;
#override
void initState() {
// super.initState();
animationController =
new AnimationController(duration: Duration(seconds: 200), vsync: this);
animation =
IntTween(begin: 0, end: photos.length - 1).animate(animationController)
..addListener(() {
setState(() {
index = animation.value;
});
});
animationController.repeat(period: Duration(seconds: 20));
}
int index = 0;
List<String> photos = [
'https://i.ibb.co/kc1mjTW/abduc-a-o-55-1.png',
'https://i.ibb.co/nmFdgs8/abduc-a-o-55-2.jpg'
];
#override
void dispose() {
// TODO: implement dispose
super.dispose();
animationController.dispose();
}
#override
Widget build(BuildContext context) {
ComicsList(Comics clist) => InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ComicsReadingPage(
comics: clist,
)),
);
},
child: PopularHq(
image: clist.pages[0].image,
name: clist.name,
));
bestm(BMovies movie) => HqWidget(
image: movie.Image,
);
final comics_scroll = Container(
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
physics: BouncingScrollPhysics(),
child: Row(
children: comicsList.map((cl) => ComicsList(cl)).toList(),
),
),
);
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
iconTheme: new IconThemeData(color: Colors.blueGrey[600]),
centerTitle: true,
title: Text(
"Schools Out",
style: TextStyle(color: Colors.blueGrey[600], fontSize: 28),
),
backgroundColor: Colors.white,
// leading:Icon(Icons.notifications,color: Colors.red,) ,
// toolbarOpacity: 0,
),
drawer: new Drawer(
child: ListView(
children: <Widget>[
new UserAccountsDrawerHeader(
accountName: new Text('Test User'),
accountEmail: new Text('testemail#test.com'),
currentAccountPicture: new CircleAvatar(
backgroundImage: new NetworkImage('http://i.pravatar.cc/300'),
),
),
new ListTile(
title: new Text('Test Navigation'),
onTap: () {
Navigator.of(context).pop();
Navigator.push(
context,
new MaterialPageRoute(
builder: (BuildContext context) => new Homepage()));
},
),
],
),
),
body: SingleChildScrollView(
physics: BouncingScrollPhysics(),
child: Column(
children: <Widget>[
Container(
color: Colors.white,
child: Column(
children: <Widget>[
ImageData(photos[index]),
// TopMovies()
],
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
// crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"HQ's",
style: TextStyle(
fontWeight: FontWeight.w900,
fontSize: 16,
color: Colors.blueGrey),
),
SizedBox(
width: 180,
),
],
),
),
hqSlider(),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
// crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Tirinhas",
style: TextStyle(
fontWeight: FontWeight.w900,
fontSize: 16,
color: Colors.blueGrey),
),
SizedBox(
width: MediaQuery.of(context).size.width * 0.65,
),
Text(
"See All",
style: TextStyle(
fontWeight: FontWeight.w900,
fontSize: 16,
color: Colors.blueGrey),
)
],
),
),
comics_scroll
],
),
));
}
}
class ImageData extends StatelessWidget {
String image;
ImageData(this.image);
#override
Widget build(BuildContext context) {
// TODO: implement build
return Container(
height: 180,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(image),
fit: BoxFit.cover,
),
borderRadius: BorderRadius.circular(8.0)),
child: Align(
alignment: Alignment.bottomCenter,
),
);
}
}
class HqWidget extends StatelessWidget {
final String image;
HqWidget({Key key, this.image});
#override
Widget build(BuildContext context) {
// TODO: implement build
return Padding(
padding: const EdgeInsets.all(8.0),
child: ClipOval(
child: Container(
height: 60,
width: 60,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(image),
fit: BoxFit.cover,
),
borderRadius: BorderRadius.circular(12.0),
boxShadow: [
BoxShadow(
offset: Offset(0.5, 1.0),
blurRadius: 5,
color: Colors.white)
]),
),
),
);
}
}
////////////////////////////////////////////
class PopularHq extends StatelessWidget {
String image, name;
PopularHq({this.image, this.name});
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: InkWell(
child: Column(
children: <Widget>[
Container(
height: 140,
width: 100,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(image),
fit: BoxFit.cover,
),
borderRadius: BorderRadius.circular(6.0),
boxShadow: [
BoxShadow(
offset: Offset(0.5, 1.0),
blurRadius: 5,
color: Colors.white)
]),
),
Container(
//width: 100,
//height: 40,
child: Text(
name,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.w600,
color: Colors.white),
),
),
],
),
),
);
}
}
////////////////////////////////////////////
final List<Comics> comicsList = [
Comics('Teste', 1, [
ComicsPage('https://i.ibb.co/nmFdgs8/abduc-a-o-55-2.jpg', 1),
ComicsPage('https://i.ibb.co/kc1mjTW/abduc-a-o-55-1.png', 2),
]),
Comics('Teste 2', 2, [
ComicsPage('https://i.ibb.co/nmFdgs8/abduc-a-o-55-2.jpg', 1),
ComicsPage('https://i.ibb.co/kc1mjTW/abduc-a-o-55-1.png', 2),
]),
Comics('Teste 3', 3, [
ComicsPage('https://i.ibb.co/nmFdgs8/abduc-a-o-55-2.jpg', 1),
ComicsPage('https://i.ibb.co/kc1mjTW/abduc-a-o-55-1.png', 2),
]),
];
class BMovies {
String Image;
int Boxc;
BMovies(this.Image);
}
hqSlider.dart (error source)
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:schools_out/pages/comicsPage.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:schools_out/entities/comicsPage.dart';
import 'package:schools_out/entities/comics.dart';
import 'dart:async';
class hqSlider extends StatefulWidget {
#override
_hqSliderState createState() => _hqSliderState();
}
class _hqSliderState extends State<hqSlider> {
Future getComics() async {
var firestore = Firestore.instance;
QuerySnapshot qn = await firestore.collection("comics").getDocuments();
return qn.documents;
}
#override
Widget build(BuildContext context) {
List<Comics> hqList = new List<Comics>();
return FutureBuilder(
future: getComics(),
builder: (_, snapshot) {
if (snapshot.data == null) {
return Center(
child: Text("Loading ..."),
);
} else if(snapshot.data.length > 0){
hqList.clear();
List<ComicsPage> pagesForThisHq = new List<ComicsPage>();
snapshot.data.forEach((element) {
element.data['pages'].forEach((page) {
pagesForThisHq.add(ComicsPage(page['image'].toString(), page['page']));
});
hqList.add(
Comics(element.data['name'], element.data['edition'], pagesForThisHq));
pagesForThisHq.clear();
});
return CarouselSlider(
autoPlay: true,
viewportFraction: 0.9,
aspectRatio: 2.4,
enlargeCenterPage: false,
items: hqList.map((hq) {
return Builder(
builder: (BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
child: GestureDetector(onTap: () {
Navigator.push<Widget>(
context,
MaterialPageRoute(
builder: (context) => ComicsReadingPage(
comics: hq,
),
),
);
}),
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(hq.pages[0].image),
fit: BoxFit.cover),
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
offset: Offset(0.2, 1.0),
blurRadius: 2,
color: Colors.grey)
]),
),
);
},
);
//////
}).toList());
} else {
return Center(
child: Text("No Content ..."),
);
}
},
);
}
}
classes Comics.dart and ComicsPage.dart
import 'package:schools_out/entities/comicsPage.dart';
class Comics {
List<ComicsPage> pages;
String name;
int edition;
Comics(this.name, this.edition, this.pages);
}
class ComicsPage {
String image;
int page;
ComicsPage(this.image, this.page);
}
Turns out the error above can be easily solved by running flutter clean
There's a second error on this code thought, it was an index error caused by this line of code in the hqSlider.dart:
pagesForThisHq.clear();
Like JS, Flutter stores reference of the data, instead of a copy, so when I cleared this array, it's copy bound to hqList was affected too, causing the index error.

Flutter Passing Document ID in Firestore Query

I am trying to figure out how to do this.
If I pass the document ID hardcoded it works. But Since I have multiple pages, I am trying to figure out how to pass it and then query it..
My main page has the following.
import 'package:flutter/material.dart';
import 'package:onlytag2/pages/category.dart';
import 'package:onlytag2/widget/maincard.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'dart:async';
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
StreamSubscription<QuerySnapshot> subscription;
List<DocumentSnapshot> snapshot;
Query collectionReference = Firestore.instance.collection("mainCategories").orderBy("title");
void initState() {
subscription = collectionReference.snapshots().listen((datasnapshot) {
setState(() {
snapshot = datasnapshot.documents;
});
});
super.initState();
}
#override
void dispose() {
subscription.cancel(); //Streams must be closed when not needed
super.dispose();
}
passData(DocumentSnapshot snap, String cat, String title) {
print(cat);
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => Category(snapshot: snap, category: cat, title: title,)));
}
#override
Widget build(BuildContext context) {
if (snapshot == null) return Center(
child: Container(
color: Colors.black,
alignment: AlignmentDirectional(0.0, 0.0),
child: Container(
color: Colors.black,
constraints: BoxConstraints(
maxHeight: 300.0,
maxWidth: 200.0,
minWidth: 150.0,
minHeight: 150.0
),
child: CircularProgressIndicator(),
),
),
);
return Scaffold(
backgroundColor: Color(0xff0E0E0F),
appBar: AppBar(
centerTitle: true,
backgroundColor: Colors.black,
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
"#",
style: TextStyle(
fontSize: 25, color: Color(0xffff9900), fontFamily: 'Dokyo'),
),
Text(
"onlytags",
style: TextStyle(color: Colors.white, fontFamily: 'Dokyo'),
)
],
),
),
body: Column(
children: <Widget>[
Expanded(
child: Column(
children: <Widget>[
Expanded(
child: ListView.builder(
itemCount: snapshot.length,
itemBuilder: (context, index) {
return InkWell(
onTap: () => passData(snapshot[index], snapshot[index].documentID.toString(), snapshot[index].data["title"] ),
child: MainCard(
title: snapshot[index].data["title"],
subtitle: snapshot[index].data["subTitle"],
image: snapshot[index].data["image"],
),
);
}),
),
],
),
),
],
),
);
}
}
The category widget is where I am having the problem.
Comment Listed where I am having the problem.
import 'package:flutter/material.dart';
import 'package:onlytag2/widget/sub.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'dart:async';
class Category extends StatefulWidget {
DocumentSnapshot snapshot;
final String category;
final String title;
Category({this.snapshot, this.category, this.title});
#override
_CategoryState createState() => _CategoryState();
}
class _CategoryState extends State<Category>{
StreamSubscription<QuerySnapshot> subscription;
List<DocumentSnapshot> snapshot;
//How do I get the category passed properly? I know it is the Document ID, but since it changes based on what button is pressed before,
//I cant figure out how to pass it..
Query collectionReference = Firestore.instance.collection("mainCategories").document(widget.category).collection("subCategories").orderBy("title");
void initState() {
subscription = collectionReference.snapshots().listen((datasnapshot) {
setState(() {
snapshot = datasnapshot.documents;
});
});
super.initState();
}
#override
void dispose() {
subscription.cancel(); //Streams must be closed when not needed
super.dispose();
}
#override
Widget build(BuildContext context) {
if (snapshot == null) return Center(
child: Container(
color: Colors.black,
alignment: AlignmentDirectional(0.0, 0.0),
child: Container(
color: Colors.black,
constraints: BoxConstraints(
maxHeight: 300.0,
maxWidth: 200.0,
minWidth: 150.0,
minHeight: 150.0
),
child: CircularProgressIndicator(),
),
),
);
return Scaffold(
backgroundColor: Color(0xff0E0E0F),
appBar: AppBar(
iconTheme: IconThemeData(
color: Color(0xffff9900),
),
centerTitle: true,
backgroundColor: Colors.black,
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
"#", style: TextStyle(fontSize: 25, color: Color(0xffff9900), fontFamily: 'Dokyo'),
),
Text(widget.title.toLowerCase(), style: TextStyle(color: Colors.white, fontFamily: 'Dokyo'),)
],
),
),
body: Column(
children: <Widget>[
Expanded(
child: Column(
children: <Widget>[
Expanded(
child: ListView.builder(
itemCount: snapshot.length,
itemBuilder: (context, index) {
return Sub(
title: snapshot[index].data["title"],
subtitle: snapshot[index].data["subTitle"],
image: snapshot[index].data["image"],
);
}),
),
Padding(padding: EdgeInsets.fromLTRB(0, 0, 0, 15),)
],
),
),
],
),
);
}
}
I have realised that the code looks shady on the comment so let me make an answer.
What you are trying to do is currently not supported in flutter as can be seen at these GitHub issues 1 and 2.
Change your code to,
class _CategoryState extends State<Category>{
StreamSubscription<QuerySnapshot> subscription;
List<DocumentSnapshot> snapshot;
Query collectionReference;
void initState() {
collectionReference = Firestore.instance.collection("mainCategories").document(widget.category).collection("subCategories").orderBy("title");
subscription = collectionReference.snapshots().listen((datasnapshot) {
setState(() {
snapshot = datasnapshot.documents;
});
});
super.initState();
}
...
Hope this helps.

How to get array data back to mobile screen from firebase (Flutter)

How to get back array data to the mobile screen.
The String in the firebase is retrieved easily but I have problem with array data.
1) main.dart :
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'firestoreservice.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'taskscreen.dart';
import 'task.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 ToDo APP',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor: Color(0xff543B7A),
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<Task> items;
FirestoreService fireServ = new FirestoreService();
StreamSubscription<QuerySnapshot> todoTasks;
#override
void initState() {
super.initState();
items=new List();
todoTasks?.cancel();
todoTasks=fireServ.getTaskList().listen((QuerySnapshot snapshot){
final List<Task> tasks=snapshot.documents
.map((documentSnapshot) => Task. fromMap(documentSnapshot.data))
.toList();
setState(() {
this.items = tasks;
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
body: Column(
children: <Widget>[
_myAppBar(context),
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height - 80,
child: ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return Stack(children: <Widget>[
// The containers in the background
Column(children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 8.0, right: 8.0),
child: Container(
width: MediaQuery.of(context).size.width,
height: 80.0,
child: Padding(
padding: EdgeInsets.only(top: 8.0, bottom: 8.0),
child: Material(
color: Colors.white,
elevation: 14.0,
shadowColor: Color(0x802196F3),
child: Center(
child: Padding(
padding: EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
'${items[index].name}',
style: TextStyle(
color: Colors.black,
fontSize: 20.0),
),
Text(
'${items[index].size}',
style: TextStyle(
color: Colors.black,
fontSize: 20.0),
),
Container(
child: Image.network(
'${items[index].imageU}',
)),
],
),
),
),
),
),
),
),
]),
]);
}),
),
],
),
);
}
Widget todoType(String icontype) {
IconData iconval;
Color colorval;
switch (icontype) {
case 'travel':
iconval = FontAwesomeIcons.mapMarkerAlt;
colorval = Color(0xff4158ba);
break;
case 'shopping':
iconval = FontAwesomeIcons.shoppingCart;
colorval = Color(0xfffb537f);
break;
case 'gym':
iconval = FontAwesomeIcons.dumbbell;
colorval = Color(0xff4caf50);
break;
case 'party':
iconval = FontAwesomeIcons.glassCheers;
colorval = Color(0xff9962d0);
break;
default:
iconval = FontAwesomeIcons.tasks;
colorval = Color(0xff0dc8f5);
//
}
return CircleAvatar(
backgroundColor: colorval,
child: Icon(iconval, color: Colors.white, size: 20.0),
);
}
Widget _myAppBar(context) {
return Container(
height: 80.0,
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
const Color(0xFFFA7397),
const Color(0xFFFDDE42),
],
begin: const FractionalOffset(0.0, 0.0),
end: const FractionalOffset(1.0, 0.0),
stops: [0.0, 1.0],
tileMode: TileMode.clamp),
),
child: Padding(
padding: const EdgeInsets.only(top: 16.0),
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Expanded(
flex: 5,
child: Container(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'ToDo Tasks',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 20.0),
),
),
),
),
Expanded(
flex: 1,
child: Container(
child: IconButton(
icon: Icon(
FontAwesomeIcons.search,
color: Colors.white,
),
onPressed: () {
//
}),
),
),
],
)),
),
);
}
}
2) task.dart
class Task{
String _name;
String _size;
Task(this._name ,this._size);
Task.map(dynamic obj){
this._name = obj['name'];
this._size=obj['size'];
List<String> imageU= new List<String>();
}
String get name=> _name;
String get size=>_size;
Task.fromMap(Map<String,dynamic> map){
this._name = map['name'];
this._size= map['size'];
this.imageU= List.from(map['images']);
}
}
3) firestoreservice.dart
import 'dart:async';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'task.dart';
final CollectionReference myCollection =
Firestore.instance.collection('products');
class FirestoreService {
Future<Task> createTODOTask(String name, String size) async {
final TransactionHandler createTransaction = (Transaction tx) async {
final DocumentSnapshot ds = await tx.get(myCollection.document());
};
return Firestore.instance.runTransaction(createTransaction).then((mapData) {
return Task.fromMap(mapData);
}).catchError((error) {
print('error: $error');
return null;
});
}
Stream<QuerySnapshot> getTaskList({int offset, int limit}) {
Stream<QuerySnapshot> snapshots = myCollection.snapshots();
if (offset != null) {
snapshots = snapshots.skip(offset);
}
if (limit != null) {
snapshots = snapshots.take(limit);
}
return snapshots;
}
}
How to get back array data to the mobile screen. The String in the firebase is retrieved easily but I have a problem with array data.
Convert task.dart to see what solution will work:
class Task{
String name;
List<String> size= new List<String>();
Task.fromMap(Map<String,dynamic> map){
this.name = map['name'];
this.size= List.from(map['size' ]);
}
}
And make sure all the documents in the image have "size" field.

Resources