Reputation: 645
I want to fetch currently logged in user data. There is a field in fire_store 'useremail'. When a user logs in, I get his ID and using 'where class' I fetch the animal's data against his ID shown below:
Widget _buildBody(BuildContext context) {
return StreamBuilder<QuerySnapshot>(
stream: Firestore.instance.collection('booking_tbl').where("useremail", isEqualTo: _firebaseUser.email.toString()).snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) return LinearProgressIndicator();
return _buildList(context, snapshot.data.documents);
},
);
}
Although it is working but it shows error on as well. I need some help to fix this issue or an alternate suggestion for this (Any suggestion or kind help would be highly appreciated):
════════ Exception caught by widgets library ══════════════════════
NoSuchMethodError was thrown building UserBookingHistoryModel(dirty, state: _UserBookingHistoryModelState#2d8c2):
The getter 'email' was called on null. Receiver: null
Tried calling: email
Probably the problem is caused by this snippet in Firebase Auth:
void initState() {
super.initState();
widget.auth.getCurrentUser().then((firebaseUserId) {
setState(() {
authStatus = firebaseUserId == null
? AuthStatus.notSignedIn
: AuthStatus.signedIn;
});
});
}
The full code of bookings.dart is here:
class _UserBookingHistoryModelState extends State<UserBookingHistoryModel> {
FirebaseAuth _auth;
FirebaseUser _firebaseUser;
@override
void initState() {
super.initState();
_auth = FirebaseAuth.instance;
_getCurrentUser();
}
_getCurrentUser () async {
_firebaseUser = await FirebaseAuth.instance.currentUser();
setState(() {
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: _buildBody(context),
);
}
Widget _buildBody(BuildContext context) {
return StreamBuilder<QuerySnapshot>(
stream: Firestore.instance.collection('booking_tbl').where("useremail", isEqualTo: _firebaseUser.email.toString()).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: 5.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.animal),
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
),
child: new ListTile(
title: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
new Text(
"${record.animal} Slaughtering",
style: new TextStyle(fontWeight: FontWeight.bold, color: Colors.black),
),
],
),
)
),
);
}
}
class Record {
final String animal;
final String user;
final DocumentReference reference;
Record.fromMap(Map<String, dynamic> map, {this.reference})
: assert(map['animal'] != null),
assert(map['user'] != null),
animal = map['animal'],
user = map['user'];
Record.fromSnapshot(DocumentSnapshot snapshot)
: this.fromMap(snapshot.data, reference: snapshot.reference);
@override
String toString() => "Record<$animal:$user>]";
}
Upvotes: 1
Views: 255
Reputation: 80914
You need to do the following:
Stream<QuerySnapshot> getData() async*{
FirebaseUser firebaseUser = await FirebaseAuth.instance.currentUser();
yield* Firestore.instance.collection('booking_tbl').where("useremail", isEqualTo: firebaseUser.email.toString()).snapshots();
}
Then inside the StreamBuilder
use getData()
:
return StreamBuilder<QuerySnapshot>(
stream: getData(),
builder: (context, snapshot) {
//....
The getData()
method is asynchronous, since you are using a StreamBuilder
then you need to return a Stream
therefore you use the async*
keyword, and you emit the result using yield*
Upvotes: 1