I want to retrive data from table in db and display it into GridView in Flutter.
At the moment I display it in a simple List but I can't display it in GridView.
Here is my code
return Scaffold(
appBar: AppBar(
title: Text("Diario di bordo"),
),
/*body: Center(
child: Text('Nessun diario presente'),
),*/
body: FutureBuilder<List>(
future: dbHelper.queryAllRows(),
initialData: List(),
builder: (context, snapshot) {
return snapshot.hasData
? ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (_, int position) {
final item = snapshot.data[position];
//get your item data here ...
return Card(
color: RandomColor().randomColor(),
child: ListTile(
title: Text(
snapshot.data[position].row[1]),
),
);
},
)
: Center(
child: CircularProgressIndicator(),
);
},
),
...
I searched on documentation and I see this piece of code
GridView.count(
// Create a grid with 2 columns. If you change the scrollDirection to
// horizontal, this produces 2 rows.
crossAxisCount: 2,
// Generate 100 widgets that display their index in the List.
children: List.generate(100, (index) {
return Center(
child: Text(
'Item $index',
style: Theme.of(context).textTheme.headline,
),
);
}),
);
I don't understand how retrive data from mytable in db and show it in GridView.
You can use the GridView.Builder
return snapshot.hasData?
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2),
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
final item = snapshot.data[index];
//get your item data here ...
return Card(
color: RandomColor().randomColor(),
child: ListTile(
title: Text(
snapshot.data[index].row[1]),
),
);
},
)
: Center(
child: CircularProgressIndicator(),
);
Related
I want to show current user data but it show empty screen and also I print data it show null data printing data
This is my database database
This is my code
Container(
child: StreamBuilder(
stream: FirebaseFirestore.instance.collection("user3").where("id",isEqualTo:FirebaseAuth.instance.currentUser!.uid).snapshots(),
builder: (BuildContext context,AsyncSnapshot<QuerySnapshot> snapshot){
if(!snapshot.hasData){
return Text("Loading please wait........");
}
print(snapshot.data!.docs);
return Center(
child: Column(
children: [
Expanded(
child: ListView.builder(
itemCount: snapshot.data!.docs.length,
itemBuilder: (BuildContext context, index) {
return
Text("Zohaib");
// Text(snapshot.data!.docs[index]["name"]);
},
)
),
],
),
);
},
),
),
I got a collection of questions in Firebase. The Categories are stored in an array. Now I want to to hide specific questions, if the user chose to hide it (User ID is stored in another array called hidden). This is what I tried:
StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection("question")
.where('category', arrayContainsAny: [widget.cid])
.where('hidden', '!=', '${user.uid}')
// also tried where('hidden', isNotEqualTo: [user.uid])
.snapshots(),
builder: (context, snapshot) {
return !snapshot.hasData
? Center(child: CircularProgressIndicator())
: ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: snapshot.data!.docs.length,
itemBuilder: (context, index) {
DocumentSnapshot data = snapshot.data!.docs[index];
return QuestionList(
de_du: data['de_du'],
de_sie: data['de_sie'],
de_ich: data['de_ich'],
qid: data['id'],
en: data['en'],
id: data.id,
documentSnapshot: data,
);
},
);
},
),
Any suggestions on how to get there?
Updated:
I tried to implement the transformation. I still get errors and do not get it to work. The errors I get: the first snapshot in transform is undefined. Expects an ) right after the first snapshot in transform. Also I get the info, that the user (provider of userid) is not used.
class _CategoryDetailState extends State<CategoryDetail> {
#override
Widget build(BuildContext context) {
var user = Provider.of<AuthProvider>(context);
return Scaffold(
appBar: AppBar(
title: Text(
this.widget.titel,
style: TextStyle(fontFamily: 'Gruppo'),
),
),
body: ListView(
children: [
Card(
margin: EdgeInsets.all(10),
child: Column(
children: [
Image.network(this.widget.image),
ListTile(
title: Text(this.widget.titel),
subtitle: Text(this.widget.description),
),
],
),
),
Center(
child: Text(
'Fragenübersicht:',
style: TextStyle(fontFamily: 'Caveat', fontSize: 25),
),
),
StreamBuilder<List<DocumentSnapshot>>(
stream: FirebaseFirestore.instance
.collection("question")
.where('category', arrayContainsAny: [widget.cid])
.snapshots()
.transform(snapshot => snapshot.docs.where(d => doc.data().hidden.contains(user.userid).toList())),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(child: CircularProgressIndicator());
} else {
return ListView.builder(
scrollDirection: Axis.vertical,
physics: ClampingScrollPhysics(),
shrinkWrap: true,
itemCount: snapshot.data!.length,
itemBuilder: (context, index) {
DocumentSnapshot data = snapshot.data![index];
return QuestionList(
de_du: data['de_du'],
de_sie: data['de_sie'],
de_ich: data['de_ich'],
qid: data['id'],
en: data['en'],
id: data.id,
documentSnapshot: data,
);
},
);
}
},
),
],
),
);
}
}
There is no way to exclude a single item from a Firestore query with a condition. What you'd need is an array-does-not-contain condition, which doesn't exist.
So that means that you'll have to read the additional items from the database, and then exclude them from the stream with something like:
StreamBuilder<List<DocumentSnapshot>>(
stream: FirebaseFirestore.instance
.collection("question")
.where('category', arrayContainsAny: [widget.cid])
.where('hidden', '!=', '${user.uid}')
.snapshots()
.transform(snapshot => snapshot.docs.where(d => doc.data().hidden.contains(user.uid)).toList(),
You'll need to update the builder too to reflect that it now gets List<DocumentSnapshot> instead of QuerySnapshot.
Can someone please explain to me how to use itemCount from ListView.Builder which is inside of an FutureBuilder.
For now my FirebaseCloud Store only has one Document , and my app is returning an infinity list of documents,
I tried to use itemCount: snapshot.data.documents.length,
however, Get the error: Class 'DocumentSnapshot' has no instance getter 'documents'. Receiver: Instance of 'DocumentSnapshot' Tried calling: documents
EDIT it should only show this document one time and one of a kind if there is more than one document related to the UID
Here is my Code
final tabs = [
Center(
child: (Scaffold(
body: FutureBuilder(
future: FirebaseFirestore.instance
.collection('users')
.doc(uid)
.get(),
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.data == null)
return CircularProgressIndicator();
DocumentSnapshot manuais = snapshot.data;
if (snapshot.hasData) {
print('okkk');
print(manuais.data()['nome']);
} else {
print('nopeeeee');
}
return Container(
padding: EdgeInsets.all(16),
child: ListView.builder(
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) {
DocumentSnapshot manuais = snapshot.data;
return Card(
color: Colors.grey[250],
child: Container(
padding: EdgeInsets.all(10),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
new Image.asset(
'Images/pdflogo.png',
width: 32,
),
Center(
child: Text(
(manuais.data()['nome'].toString()),
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 16),
),
),
ButtonBar(
children: <Widget>[
FlatButton(
child: const Text(
'Compartilhar / Download'),
onPressed: () async {
var request = await HttpClient()
.getUrl(Uri.parse(manuais
.data()['documento']));
var response =
await request.close();
Uint8List bytes =
await consolidateHttpClientResponseBytes(
response);
await Share.file(
'ESYS AMLOG',
'Manual.pdf',
bytes,
'image/jpg');
}),
],
),
],
),
),
);
}),
);
})))),
````
You have to do:
itemCount : 1
Since you are only retrieving one document, when you do:
FirebaseFirestore.instance
.collection('users')
.doc(uid)
.get()
The above will always retrieve one document since the document id will always be unique.
You need to get length like this.
itemCount: snapshot.data.data().length,
if (snapshot.hasData) {
print('okkk');
print(manuais.data()['nome']);
return Container(
padding: EdgeInsets.all(16),
child: ListView.builder(
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) {
DocumentSnapshot manuais = snapshot.data;
return Card(
color: Colors.grey[250],
child: Container(
padding: EdgeInsets.all(10),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
new Image.asset(
'Images/pdflogo.png',
width: 32,
),
Center(
child: Text(
(manuais.data()['nome'].toString()),
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 16),
),
),
ButtonBar(
children: <Widget>[
FlatButton(
child: const Text(
'Compartilhar / Download'),
onPressed: () async {
var request = await HttpClient()
.getUrl(Uri.parse(manuais
.data()['documento']));
var response =
await request.close();
Uint8List bytes =
await consolidateHttpClientResponseBytes(
response);
await Share.file(
'ESYS AMLOG',
'Manual.pdf',
bytes,
'image/jpg') ...(all your brackets go here)
}
I have saved my phone's call list to a database and now I want to create a ListView from this database. I have already written this code. But it is not working. what is wrong with my code?
database_helper.dart
...
Future<List<Map<String, dynamic>>> queryAllRows() async {
Database db = await instance.database;
return await db.query(table);
}
...
my_home.dart
...
FutureBuilder(
future: db.queryAllRows(),
builder: (context, snapshot) {
if (!snapshot.hasData)
return Center(child: CircularProgressIndicator());
List entries = snapshot.data.toList();
return Scrollbar(
child: ListView.builder(
itemBuilder: (context, index) {
var entry = entries[index];
var mono = TextStyle(fontFamily: 'monospace');
return Column(
children: <Widget>[
Divider(),
Text('NUMBER : ${entry.number}', style: mono),
Text('NAME : ${entry.name}', style: mono),
Text('TYPE : ${entry.callType}', style: mono),
Text(
'DATE : ${DateTime.fromMillisecondsSinceEpoch(entry.timestamp)}',
style: mono),
Text('DURATION : ${entry.duration}',
style: mono),
],
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
);
},
itemCount: entries.length,
),
);
})
...
You need to use ConnectionState inside your builder. Look at this code template: (Currently the builder return your widget without waiting for the future to complete)
return FutureBuilder<List<Map<String, dynamic>>>(
future: db.queryAllRows(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
// future complete
if (snapshot.hasError || !snapshot.hasData) {
return Center(child: CircularProgressIndicator());
}
// future complete with no error and has data
List entries = snapshot.data.toList();
return Scrollbar(
child: ListView.builder(
itemBuilder: (context, index) {
var entry = entries[index];
var mono = TextStyle(fontFamily: 'monospace');
return Column(
children: <Widget>[
Divider(),
Text('NUMBER : ${entry.number}', style: mono),
Text('NAME : ${entry.name}', style: mono),
Text('TYPE : ${entry.callType}', style: mono),
Text(
'DATE : ${DateTime.fromMillisecondsSinceEpoch(entry.timestamp)}',
style: mono),
Text('DURATION : ${entry.duration}', style: mono),
],
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
);
},
itemCount: entries.length,
),
);
}
// return loading widget while connection state is active
else {
return Center(child: CircularProgressIndicator());
}
});
Background: I'm writing an app in which you can store the plus points and fives of a class.
I do this with Flutter and Firebase. My Firestore database collection is called 'mates' and it has several documents, with a unique, auto-ID. Every document has three fields: a name(string), points(number), fives(number).
I have made this far with the help of this tutorial: https://www.youtube.com/watch?v=DqJ_KjFzL9I&t=591s
I want to modify the GUI a bit, in each listtile I display the name, button for decrementing points, the value of points, button for incrementing points, button for decrementing fives, value of fives, button for incrementing fives and a button for setting the value of fives to zero.
My question would be, that how can I refer to the fields(points, fives) of the database when changing their values?
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Widget _buildListItem(BuildContext context, DocumentSnapshot document){
return ListTile(
title: Row(
children: [
Expanded(
child: Text(
document["Name"],
style: Theme.of(context).textTheme.headline,
)
),
Container(
decoration: const BoxDecoration(
color: Color(0xffddddff)
),
padding: const EdgeInsets.all(10.0),
child: Text(
document['Points'].toString(),
style: Theme.of(context).textTheme.display1,
),
),
Container(
child: Row(
children: <Widget>[
IconButton(
icon: Icon(Icons.keyboard_arrow_left),
iconSize: 30,
onPressed: (){
setState(() {
if(points!=0) { //I mean here
points--; //I mean here
}
});
}
),
Text(
"$points", //I mean here
style: TextStyle(
fontSize: 30
),
),
IconButton(
icon: Icon(Icons.keyboard_arrow_right),
iconSize: 30,
onPressed: (){
setState(() {
points++; //I mean here
if(points==10){ //I mean here
points=0; //I mean here
fives++; //I mean here
}
});
}
),
Text(
"$fives", //I mean here
style: TextStyle(
fontSize: 30
),
),
IconButton(
icon: Icon(Icons.check_circle),
iconSize: 30,
onPressed: (){
setState(() {
fives=0; //I mean here
});
}
),
]
)
),
],
),
);
}
#override
Widget build(BuildContext context) {
return Center(
child: Scaffold(
appBar: AppBar(
title: Text("Punkte++"),
centerTitle: true,
),
body: StreamBuilder(
stream: Firestore.instance.collection("mates").snapshots(),
builder: (context, snapshot) {
if(!snapshot.hasData) return const Text("Loading...");
return ListView.builder(
itemExtent: 80.0,
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) =>
_buildListItem(context, snapshot.data.documents[index]),
);
}
),
)
);
}
}