STBox
STBox

Reputation: 645

Flutter/Firebase - Error in fetching currently logged in user data

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

Answers (1)

Peter Haddad
Peter Haddad

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

Related Questions