Firestore <QuerySnapshot> - firebase

I have a problem with my class GetInfo.
There is an error with .
The name 'QuerySnapshot' is defined in the libraries 'package:cloud_firestore/cloud_firestore.dart' and 'package:firebase/src/firestore.dart (via package:firebase/firestore.dart)'.
Try using 'as prefix' for one of the import directives, or hiding the name from all but one of the imports.
class GetInfo extends StatelessWidget {
const GetInfo({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Material(
child: StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance.collection('stories').snapshots(),
builder: (context, snapshot) {
if (snapshot.hasError) {
return Text('Something went wrong');
}
if (snapshot.connectionState == ConnectionState.waiting) {
return Text('Loading');
}
return new ListView(
children: snapshot.data!.docs.map((document) {
return new ListTile(
title: Text(document.get('display_name')),
subtitle: Text(document.get('profession')),
);
}).toList(),
);
}),
);
}
}
I am using Flatter with Firebase, Firestore. I am trying to follow one of the courses but it seems this is based on old Firebase Version and I don't know how to fix the code. Any advice? Thanks for your answers!

the package is updated please check the example.
body: StreamBuilder<QuerySnapshot<Movie>>(
stream: moviesRef.queryBy(query).snapshots(),
builder: (context, snapshot) {
if (snapshot.hasError) {
return Center(
child: Text(snapshot.error.toString()),
);
}
if (!snapshot.hasData) {
return const Center(child: CircularProgressIndicator());
}
final data = snapshot.requireData;
return ListView.builder(
itemCount: data.size,
itemBuilder: (context, index) {
return _MovieItem(
data.docs[index].data(),
data.docs[index].reference,
);
},
);
},
),
final moviesRef = FirebaseFirestore.instance
.collection('firestore-example-app')
.withConverter<Movie>(
fromFirestore: (snapshots, _) => Movie.fromJson(snapshots.data()!),
toFirestore: (movie, _) => movie.toJson(),
);

Related

Exception has occurred. _CastError (Null check operator used on a null value)

I have problem with this code,
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
const HomePage({ Key? key }) : super(key: key);
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
FirebaseFirestore firestore = FirebaseFirestore.instance;
CollectionReference users = FirebaseFirestore.instance.collection('users');
Stream<QuerySnapshot<Map<String, dynamic>>> collectionStream = FirebaseFirestore.instance.collection('users').snapshots();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Home Page'),
),
body: StreamBuilder<QuerySnapshot<Map<String, dynamic>>>(
stream: collectionStream,
builder: (context, snapshot) {
return Container(
child: ListView.builder(
itemCount: snapshot.data!.docs.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(snapshot.data!.docs[index].data()['name']),
trailing: IconButton(
icon: const Icon(Icons.delete),
onPressed: () {
users.doc(snapshot.data!.docs[index].id).delete();
},
),
);
}
),
);
},
),
);
}
}
This line that makes this program error, operator (!):
snapshot.data!.docs.length
snapshot.data!.docs[index].data()['name']
snapshot.data!.docs[index].id
initially this code does not error, but when I rerun it appears : Exception has occurred. _CastError (Null check operator used on a null value). I've tried to fix it but still failed. Is there a way to solve this problem ?
This error means that the snapshot.data is null.
And you're using the null-check operator on it in the line snapshot.data!.
Solution:
You need to check if the data is null and display something like a loading screen while the app waits for snapshot.data to have a value like this:
body: StreamBuilder<QuerySnapshot<Map<String, dynamic>>>(
stream: collectionStream,
builder: (context, snapshot) {
if (snapshot.data == null) {
return Center(child: CircularProgressIndicator());
}
return Container(
child: ListView.builder(
itemCount: snapshot.data.docs.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(snapshot.data.docs[index].data()['name']),
trailing: IconButton(
icon: const Icon(Icons.delete),
onPressed: () {
users.doc(snapshot.data.docs[index].id).delete();
},
),
);
},
),
);
}
)
And since you're checking if snapshot.data is null, you can remove the null-check operator from its usage.
So snapshot.data! in snapshot.data!.docs.length becomes snapshot.data like snapshot.data.docs.length.

Flutter Firestore Error: Field does not exist within the DocumentSnapshotPlatform

I'm having trouble reading data from firestore. I want to display a user's name on screen after it is stored in firestore.
firestore document
my code is as follows, and thank you in advance for any assistance given:
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class Test extends StatefulWidget {
#override
_TestState createState() => _TestState();
}
class _TestState extends State<Test> {
final db = FirebaseFirestore.instance.collection('users').snapshots();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Test'),
),
body: StreamBuilder<QuerySnapshot>(
stream: db,
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
} else
return ListView(
children: snapshot.data!.docs.map((doc) {
return Card(
child: ListTile(
title:
// Text(doc.data()['title']),
Text(doc.get('First name')
),
));
}).toList(),
);
},
),
final Stream<DocumentSnapshot<Map<String, dynamic>>> db = FirebaseFirestore.instance
.collection('users')
.doc('Personal details')
.snapshots();
...
body: StreamBuilder<DocumentSnapshot>(
stream: db,
builder:
(BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
if (snapshot.hasError) return Text('Something went wrong');
if (snapshot.connectionState == ConnectionState.waiting)
return CircularProgressIndicator();
dynamic data = snapshot.data.data();
print(data);
print(data['First name']); // should print 'Guy'
print(data['Last name']); // should print 'Fang'
return Text(data['First name']);
},
),
In the code you showed, you are listening to the 'users' collection, instead, listen to the document 'Personal details' as shown above.

"NoSuchMethodError: The getter 'docs' was called on null" Error Flutter Firebase

I'm getting the error "NoSuchMethodError: The getter 'docs' was called on null. Receiver: null Tried Calling: docs" whenever I try to use .orderby("POST_ID", descending: true. If someone has an answer to why I'm getting this error and how to fix it please help!
Here is my code:
Container(
margin: EdgeInsets.only(top: 100.0),
child: StreamBuilder(
stream: FirebaseFirestore.instance
.collection("Cities")
.doc(globals.selectedCity)
.collection("Posts")
.orderBy("POST_ID", descending: true)
.where("Category", isEqualTo: globals.selectedCategory)
.snapshots(),
builder: (context, postSnapshot) {
return ListView.builder(
itemCount: postSnapshot.data.docs.length,
itemBuilder: (BuildContext context, int index) {
switch (postSnapshot.data.docs[index]["Type"]) {
case "Image":
return new ImageCard(
imageLink: postSnapshot.data.docs[index]
["ImageLink"],
imageDescription: postSnapshot.data.docs[index]
["ImageDescription"],
posterName: postSnapshot.data.docs[index]
["PosterName"],
);
break;
case "Text":
return new TextCard(
postText: postSnapshot.data.docs[index]
["PostText"],
posterName: postSnapshot.data.docs[index]
["PosterName"],
);
break;
Problem is here:
(postSnapshot.data.docs[index]["Type"])
You have to ensure first that you got the data from firestore. In your case when connection state is connecting or if snapshot has error you invoke docs on null object. Consider building widget tree with checks like this:
class UserInformation extends StatelessWidget {
#override
Widget build(BuildContext context) {
CollectionReference users = FirebaseFirestore.instance.collection('users');
return StreamBuilder<QuerySnapshot>(
stream: users.snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) {
return Text('Something went wrong');
}
if (snapshot.connectionState == ConnectionState.waiting) {
return Text("Loading");
}
return new ListView(
children: snapshot.data.docs.map((DocumentSnapshot document) {
return new ListTile(
title: new Text(document.data()['full_name']),
subtitle: new Text(document.data()['company']),
);
}).toList(),
);
},
);
}
}

Future Builder don't show data from Cloud Firestore

I load data from Cloud Firestore from Firebase. In the print statement in the function loadAssignments() the loaded data are showing correct. But when i will show the data in the Text widget with the widget FutureBuilder it doesn't show the data and i don't know why. Can anyone please help me?
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class AssignmentPage extends StatefulWidget {
#override
_AssignmentPageState createState() => _AssignmentPageState();
}
class _AssignmentPageState extends State<AssignmentPage> {
Future _loadAssignments;
QuerySnapshot _assignments;
#override
void initState() {
super.initState();
_loadAssignments = loadAssignments();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Bühlmaier App'),
centerTitle: true,
automaticallyImplyLeading: false,
),
body: FutureBuilder(
future: _loadAssignments,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return ListView.builder(
itemCount: _assignments.documents.length,
itemBuilder: (context, index) {
return Card(
child: ListTile(
leading: Text('${_assignments.documents[index].data['Name'].toString()}'),
),
);
});
} else if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
}
return Center(child: CircularProgressIndicator());
},
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () => toPage(NewAssignmentPage()),
),
);
}
Future<void> loadAssignments() async {
_assignments = await Firestore.instance.collection('assignments').getDocuments();
for (int i = 0; i < _assignments.documents.length; i++) {
print('DATEN: ' + _assignments.documents[i].data['Name'].toString());
}
setState(() {});
}
}
When i add the following code:
else if (snapshot.connectionState == ConnectionState.waiting) {
return Text("No data");
}
it works, but when i edit the code to:
else if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator();
}
it don't load the data and the CircularProgressIndicator() is not moving.
Use the method in the future property:
FutureBuilder(
future: loadAssignments(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return ListView.builder(
shrinkWrap: true,
itemCount: snapshot.data.documents.length,
itemBuilder: (BuildContext context, int index) {
return Card(
child: ListTile(
leading: Text('${snapshot.data.documents[index].data['Name'].toString()}'),
),
);
});
} else if (snapshot.connectionState == ConnectionState.none) {
return Text("No data");
}
return CircularProgressIndicator();
},
),
Change the method to the following:
Future<QuerySnapshot> loadAssignments() async {
return await Firestore.instance.collection('assignments').getDocuments();
}

Get data from Cloud firestore and displays them into widget

Below you can see a code where I want to display data that I have collected from a registration form in Flutter.
the registration form push the data to a collection called " user " then some other documents data are pushed as:
name - email etc...
As you can see by XXXX I want that the data I retrieve from cloud firestore be shown into the widget:
Below the code:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class WelcomeScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.pink,
body: MainWelcome(),
);
}
}
class MainWelcome extends StatefulWidget {
#override
_MainWelcomeState createState() => _MainWelcomeState();
}
class _MainWelcomeState extends State<MainWelcome> {
final databaseReference = Firestore.instance;
Future<QuerySnapshot> getData() async {
return await Firestore.instance.collection("user").getDocuments();
}
#override
Widget build(BuildContext context) {
return FutureBuilder(
future: getData(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
snapshot.data.documents.forEach((element) {
Center(
child: Text(
'Benvenuta ${element.data["name"]}',
style: TextStyle(fontSize: 20, color: Colors.white),
),
);
});
} else if (snapshot.connectionState == ConnectionState.none) {
return Text("No data");
}
return Center(child: CircularProgressIndicator());
},
);
}
}
You need to use a FutureBuilder widget to display the data in the widget tree:
Create a method that returns the data:
Future<QuerySnapshot> getData() async {
return await Firestore.instance
.collection("user")
.where("email", isEqualTo: "email_here")
.getDocuments();
}
Then inside the build() method do the following:
FutureBuilder(
future: getData(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return ListView.builder(
shrinkWrap: true,
itemCount: snapshot.data.documents.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
contentPadding: EdgeInsets.all(8.0),
title:
Text(snapshot.data.documents[index].data["name"]),
);
});
} else if (snapshot.connectionState == ConnectionState.none) {
return Text("No data");
}
return CircularProgressIndicator();
},
),

Resources