Hi guys im learning flutter and i have an error whenever i try to call documents in the listbuilder it gives me an error but when i tried it on a floatingactionbutton to get my texts it worked fine instead of documents i used docs it worked but for this one it doesnt work out so please help me im trying to get item counts here's my full code below
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class ChatScreen extends StatelessWidget {
const ChatScreen({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: StreamBuilder(
stream: FirebaseFirestore.instance
.collection('chats/Dx7QFvCELN2XFWumVWOY/messages')
.snapshots(),
builder: (ctx, streamSnapshot) {
return new ListView.builder(
itemCount: streamSnapshot.data.documents.length, //the error is in here
itemBuilder: (ctx, index) => Container(
padding: EdgeInsets.all(8),
child: Text("This Works"),
),
);
},
),
floatingActionButton:
FloatingActionButton(child: Icon(Icons.add), onPressed: () {}),
);
}
}
You're probably getting a null pointer exception. Initially the builder function is called before the data is returned from Firestore. You can check for that and display another Widget while there isn't any data yet:
builder: (ctx, streamSnapshot) {
if(!streamSnapshot.hasData) return CircularProgressIndicator();
return new ListView.builder(
Also, I think you might need to use docs instead of documents. The type of streamSnapshot should be AsyncSnapshot<QuerySnapshot> and according to the documentation of QuerySnapshot, there's only a docs getter.
Related
I'm new to flutter and I'm trying to retrieve a list of categories from the firebase cloud firestore into my flutter application using StreamBuilder.
Im using flutter 2.8.0 and cloud_firestore: ^3.1.7
this my firestore documents: categories collection
here is my code:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:harfanah/shared/loading.dart';
class categoriesMod extends StatefulWidget {
const categoriesMod({ Key? key }) : super(key: key);
#override
_categoriesModState createState() => _categoriesModState();
}
class _categoriesModState extends State<categoriesMod> {
#override
Widget build(BuildContext context) {
return Scaffold (
body: StreamBuilder(
stream: FirebaseFirestore.instance.collection('categories').snapshots(),
builder: (context, snapshot) {
if(!snapshot.hasData) {
return loading();
}
return ListView.builder(
itemCount: ,
itemBuilder: ,
);
},
),
);
}
}
I'm really confused about how can I use ItemCount and ItemBuilder. I found many many solution that say i should use something like this: itemCount: snapshot.data.documents.length but it does not work. data does not even have any attributes other than these: data attributes
You need to specify the type of the StreamBuilder then you can use the properties/methods available in the class QuerySnapshot:
class _categoriesModState extends State<categoriesMod> {
#override
Widget build(BuildContext context) {
return Scaffold (
body: StreamBuilder<QuerySnapshot<Map<String,dynamic>>>(
stream: FirebaseFirestore.instance.collection('categories').snapshots(),
builder: (context, snapshot) {
if(!snapshot.hasData) {
return loading();
}
return ListView.builder(
itemCount: snapshot.data!.docs.length,
itemBuilder: (context,index){
return ListTile(
title: snapshot.data!.docs[index].data()["code"],
leading: snapshot.data!.docs[index].data()["name"],
);
} ,
);
},
),
);
}
}
What's wrong? I'm beginner in Flutter, and getting this error...
Working with Flutter + Firebase, this is a test to show list of People... I'm learning, sorry for fool mistakes.
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_core/firebase_core.dart';
class info extends StatelessWidget {
#override
Widget build(BuildContext context) {
final content = StreamBuilder(
stream: FirebaseFirestore.instance.collection('listas').snapshots(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (!snapshot.hasData) return const Text('Carregando...');
return ListView.builder(
itemCount: snapshot.data.documents.length,
itemBuilder: (BuildContext context, int index){
DocumentSnapshot doc = snapshot.data.documents[index];
return ListTile(
leading: Icon(Icons.ac_unit),
title: Text(doc['nome']),
trailing: GestureDetector(
onTap: (){
},
),
);
},
);
},
);
}
}
You need to return the widget you saved in the content variable.
I have stored a news article content into firebase as shown here
P.S- Here links in curly braces attach to text preceding it.
Here is my code to fetch it where "Content" is my field-
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
class Test extends StatelessWidget {
#override
Widget build(BuildContext context) {
return StreamBuilder(
stream: FirebaseFirestore.instance
.collection("Insights")
.orderBy("Time", descending: true)
.snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
return ListView.builder(
itemCount: snapshot.data.docs.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Inkwell(
child: Text(
(snapshot.data.docs[index]['Content'])
.toString()
.replaceAll("\\n", "\n"),
style: TextStyle(fontSize: 18),
)),
);
});
});
}
}
I am getting the output as simple text. While I want to show data on flutter application as shown here output
P.S - Blue color texts are clickable strings which will redirect to links attached as shown in input data in curly braces.
How can I achieve this? Is there any way to store data in firebase so that I can get output as shown in output image or is there any way to handle it in flutter application?
Check this, RichText class here
You have to parse string and obtain the text with link and create RichText widget accordingly.
I'm having issues with getting messages fetched from Firebase Cloud Firestore. The error being displayed is: 'Error: The getter 'docs' isn't defined for the class 'Object' - 'Object' is from 'dart:core'.'
Below is my code:
class ChatScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: StreamBuilder<Object>(
stream: FirebaseFirestore.instance
.collection('chats/EKLJIb8ZfRoDTqxkkJaB/messages')
.snapshots(),
builder: (context, chatSnapshot) {
return ListView.builder(
itemCount: chatSnapshot.data.**docs**.length,
itemBuilder: (ctx, index) => Container(
padding: EdgeInsets.all(8),
child: Text('this work'),
),
);
}),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: null,
),
);
}
}
Change this:
body: StreamBuilder<Object>(
into this:
body: StreamBuilder<QuerySnapshot>(
The docs is a property under the class QuerySnapshot and not class Object.
You have to specify the type that your stream returns. So if you have a stream of type Stream<QuerySnapshot>, then you add that type as an argument to the StreamBuilder as you have seen in the code above.
In the new cloud_firestore package, the snapshots() method returns Stream<QuerySnapshot<Map<String, dynamic>>> therefore you would do:
body: StreamBuilder<QuerySnapshot<Map<String, dynamic>>>(
Adding dynamic might solve this issue, but it's preferable to add the type that is being returned because that way the editor or IDE will provide you with the code completion.
I have solved it by adding the datatype as dynamic after StreamBuilder, in my case the answer "Peter Haddad" didn't work for me, I had the exact same error.
This is how I solved it:
StreamBuilder<dynamic>(....Your Code here....)
My code builds a ListView of ListTiles, with each ListTile getting data from a cloud firestore database.
When I activate the onTap of a ListTile I would like to route to a new page and pass the specific data for that tile to the new page.
The page which I am building the list view on I have passed variables to without problems, however I cannot get the same method to work on this page.
I am fairly new to flutter and dart. My first assumption is that maybe it requires a stateful widget in order to accomplish this? However I am not exactly sure how to implement this.
import 'package:flutter/material.dart';
import 'package:menu/screens/menu/detail.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_storage/firebase_storage.dart';
class Menu extends StatelessWidget {
final String barcode;
// receive data from the FirstScreen as a parameter
Menu({Key key, #required this.barcode}) : super(key: key);
Widget _buildListItem(BuildContext context, DocumentSnapshot document) {
return ListTile(
leading: Icon(Icons.fastfood),
title: Text(document['item'] ?? '*name*'),
subtitle: Text( document['description'] ?? '*description*'),
isThreeLine: true,
onTap: (){
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Detail(),
),);
},
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Menu'),
),
body: StreamBuilder(
stream: Firestore.instance.collection(barcode).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]),
);
}),
);
}
}
Pass document as parameter to Detail
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Detail(document), // <-- document instance
),);
Detail widget of course need to take document as parameter:
class Detail extends ... {
Detail(this.document);
final DocumentSnapshot document;
}
as described in https://flutter.io/docs/cookbook/navigation/passing-data