Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I am trying to get firestore data from streambuilder of other page, and it shows me the below error
error: The method 'data' isn't defined for the type 'QuerySnapshot'.
(undefined_method at [phonebook_admin]lib\Screens\DetailPage\DetailPage.dart:20)
The below is the code
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class DetailPage extends StatefulWidget {
final QuerySnapshot contactDetail;
DetailPage({this.contactDetail});
#override
_DetailPageState createState() => _DetailPageState();
}
class _DetailPageState extends State<DetailPage> {
#override
Widget build(BuildContext context) {
return Container(
child: Card(
child: ListTile(
title: Text(widget.contactDetail.data()['name']),
subtitle: Text(widget.contactDetail.data()['email']),
),
),
);
}
}
You should do the following:
return ListView.builder(
shrinkWrap: true,
itemCount: widget.contactDetail.docs.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: Text(widget.contactDetail.docs[index].data()['name']),
subtitle: Text(widget.contactDetail.docs[index].data()['email']),
);
},
);
QuerySnapshot returns a list of documents with the content of the documents, therefore you need to use a ListView.builder
Related
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.
I'm stuck on this problem. I have been trying to render items from my Firestore collection. Everytime I try to retrieve it, I keep getting this error:
"Closure call with mismatched arguments: function '[]'
Receiver: Closure: () => Map<String, dynamic> from Function 'data':.
Tried calling: []("title")
Found: []() => Map<String, dynamic>"
I have tried to look online for solutions but I feel a bit stuck on what I am supposed to do. I have commented the part that is causing an error in the ListTile. This is something I have been stuck on in the past few days. I have all the dependencies installed such as the Firestore one so I don't think it is a dependency issue. Although I would greatly appreciate anyone who is able to help me by any chance.
import 'package:flutter/material.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:tanbo_mobile/errorpage.dart';
import 'dart:async';
import 'package:cloud_firestore/cloud_firestore.dart';
class HomeTab extends StatefulWidget {
#override
_HomeTabState createState() => _HomeTabState();
}
class _HomeTabState extends State<HomeTab> {
Future getPosts() async {
var firestoreReference = FirebaseFirestore.instance;
QuerySnapshot qn = await firestoreReference.collection('posts').get();
return qn.docs;
}
#override
Widget build(BuildContext context) {
return Container(
child:
FutureBuilder(
future: getPosts(),
builder: (_, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
);
} else if (snapshot.connectionState == ConnectionState.done) {
return ListView.builder(
// The length of our data we will return
itemCount: snapshot.data.length,
itemBuilder: (_, index) {
return ListTile(
// This line is causing the errors!
title: Text(snapshot.data[index].data['text']),
);
}
);
}
return Center(
child: CircularProgressIndicator(),
);
},
),
);
}
}
Image of error in application
Firestore data structure
DocumentSnapshot.data() is a method not a getter, therefore it's necessary to include the parentheses to actually call the method and obtain the returned Map. This is why dart is confused and throws an error as you're trying to use the [] operator on a function reference.
Replace the line that is giving you errors with the following:
title: Text(snapshot.data[index].data()['text']),
Here there are my two Dart file from that I retrieve my Video from firestore but in that, I made video array and try to retrieve it but it gives me an error , if I am doing it with string instead of array It looks fine but in my project, I am requiring array so please help me to finger out.
My cloud firestore looks like is: collection(Course)=>autoid=>doucuments(video array)=>([0]url [1]url2)
Here is my 2 Dart file please correct my code what is wrong in this case when I am running this I got error Like :
Error: list is not a subtype of type 'string'.
code:main.dart and chewie_list_item.dart
main.dart:It is for retrieve data
import 'chewie_list_item.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';`enter code here`
import 'package:video_player/video_player.dart';
void main() {
FlutterError.onError = (FlutterErrorDetails details) {
FlutterError.dumpErrorToConsole(details);
if (kReleaseMode) exit(1);
};
runApp(MaterialApp(
home: CourseApp(),
));
}
class CourseApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Flutter Demo"),
),
body: StreamBuilder(
stream: Firestore.instance.collection("courses").snapshots(),
builder: (context, snapshot) {
return ListView.builder(
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) {
DocumentSnapshot courses = snapshot.data.documents[index];
return (ChewieListItem(
videoPlayerController: VideoPlayerController.network(
courses['video'] ?? 'default'),
));
},
);
},
));
}
}
[code 2: chewie_list_item.dart]: It for chewie video player.
import 'package:chewie/chewie.dart';
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
class ChewieListItem extends StatefulWidget {
// This will contain the URL/asset path which we want to play
final VideoPlayerController videoPlayerController;
final bool looping;
ChewieListItem({
#required this.videoPlayerController,
this.looping,
Key key,
}) : super(key: key);
#override
_ChewieListItemState createState() => _ChewieListItemState();
}
class _ChewieListItemState extends State<ChewieListItem> {
ChewieController _chewieController;
#override
void initState() {
super.initState();
// Wrapper on top of the videoPlayerController
_chewieController = ChewieController(
videoPlayerController: widget.videoPlayerController,
aspectRatio: 16 / 9,
// Prepare the video to be played and display the first frame
autoInitialize: true,
looping: widget.looping,
// Errors can occur for example when trying to play a video
// from a non-existent URL
errorBuilder: (context, errorMessage) {
return Center(
child: Text(
errorMessage,
style: TextStyle(color: Colors.white),
),
);
},
);
}
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Chewie(
controller: _chewieController,
),
);
}
#override
void dispose() {
super.dispose();
// IMPORTANT to dispose of all the used resources
widget.videoPlayerController.dispose();
_chewieController.dispose();
}
}
So mainly I have not any idea hoe to retrieve this video array from my firebase please give the correct code.
This question already has answers here:
No Firebase App '[DEFAULT]' has been created - call Firebase.initializeApp() in Flutter and Firebase
(27 answers)
"The operator '[]' isn't defined" error when using .data[] in flutter firestore
(6 answers)
The getter 'instance' isn't defined for the type 'Firestore'
(2 answers)
Closed 2 years ago.
I'm trying to fetch data from Cloud Firestore on flutter but as soon as I import the cloud_firestore.dart package, the app doesn't even build and crashes instantly with a lot of errors.
https://hastebin.com/esuzizuzod.sql this is the error it throws.
And this is the code
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_core/firebase_core.dart';
Future<void> main() async {
await Firebase.initializeApp();
runApp(MyApp());
}
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Firestore Demo"),
),
body: StreamBuilder(
stream: FirebaseFirestore.instance.collection("users").snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Text("Loading data...Please wait!");
} else {
return Column(
children: <Widget>[
Text(snapshot.data.documents[0]["name"]),
Text(snapshot.data.documents[0]["age"]),
Text(snapshot.data.documents[0]["role"]),
],
);
}
}),
);
}
}
I have also implemented all the packages in the pubspec.yaml file.
Does anyone know how to fix this?
Thanks
This happens in my main application
and
I replicate it with the given codelabs:
https://codelabs.developers.google.com/codelabs/flutter-firebase/index.html?index=..%2F..index#10
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Baby Names',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() {
return _MyHomePageState();
}
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Baby Name Votes')),
body: _buildBody(context),
);
}
Widget _buildBody(BuildContext context) {
return StreamBuilder<QuerySnapshot>(
stream: Firestore.instance.collection('baby').snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) return LinearProgressIndicator();
return _buildList(context, snapshot.data.documents);
},
);
}
Widget _buildList(BuildContext context, List<DocumentSnapshot> snapshot){
return ListView(
padding: const EdgeInsets.only(top: 20.0),
children: snapshot.map((data) => _buildListItem(context, data)).toList(),
);
}
Widget _buildListItem(BuildContext context, DocumentSnapshot data) {
final record = Record.fromSnapshot(data);
return Padding(
key: ValueKey(record.name),
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(5.0),
),
child: ListTile(
title: Text(record.name),
trailing: Text(record.votes.toString()),
onTap: () => print(record),
),
),
);
}
}
class Record {
final String name;
final int votes;
final DocumentReference reference;
Record.fromMap(Map<String, dynamic> map, {this.reference})
: assert(map['name'] != null),
assert(map['votes'] != null),
name = map['name'],
votes = map['votes'];
Record.fromSnapshot(DocumentSnapshot snapshot)
: this.fromMap(snapshot.data, reference: snapshot.reference);
#override
String toString() => "Record<$name:$votes>";
}
Only plugin i use is the cloud_firestore 0.9.5+2.You need to be patient with this testing process please. You will not see the issue right away. Run the app first, set this project up. You can follow the directions in the given codelabs. Once everything is set up on front end and backend(create documents on firstore). Go have a lunch break, dinner, play video games or hang out with friends. Come back after 1 hour. Run the app, you will be incurred charges for those reads as new. Do it again, come back 1 hour and it will happen again
How to replicate it in real life:
Start this app by given code from codelabs. Run it, it should incur 4 document reads if you stored 4 documents into the firestore.
Start it up again. No reads are charged. Great it works! but no, it really doesnt.
I wake up next day and open up the app, im charged 4 reads. Okay maybe some magic happened. I restart it right away and no charges incur(great!). Later in 1 hour, i start up the app and I get charged 4 reads to display the very same 4 documents that have not been changed at all.
The problem is, on app start up. It seems to be downloading documents from the query snapshot. No changes have been made to the documents. This stream-builder has been previously run many times.
Offline mode(airplane mode), the cached data is displayed with no issues.
in my main application for example, I have a photoUrl and on fresh App start, you can see it being loaded from the firestore(meaning downloaded as a fresh document thus incurring a READ charge). I restart my main application, no charges are made and photo does not refresh(great!). 1 hour later i start up the app and charges are made for every document I retrieve(none of changed).
Is this how cloud firestore is supposed to behave?
From what I have read, its not supposed to behave like this :(
You should not do actual work in build() except building the widget tree
Instead of code like this in build
stream: Firestore.instance.collection('baby').snapshots(),
you should use
Stream<Snapshot> babyStream;
#override
void initState() {
super.initState();
babyStream = Firestore.instance.collection('baby').snapshots();
}
Widget _buildBody(BuildContext context) {
return StreamBuilder<QuerySnapshot>(
stream: babyStream,
builder: (context, snapshot) {
if (!snapshot.hasData) return LinearProgressIndicator();
return _buildList(context, snapshot.data.documents);
},
);
}
The FutureBuilder docs don't mention it that explicitly but its the same
https://docs.flutter.io/flutter/widgets/FutureBuilder-class.html
The future must have been obtained earlier, e.g. during
State.initState, State.didUpdateConfig, or
State.didChangeDependencies. It must not be created during the
State.build or StatelessWidget.build method call when constructing the
FutureBuilder. If the future is created at the same time as the
FutureBuilder, then every time the FutureBuilder's parent is rebuilt,
the asynchronous task will be restarted.