Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter Firestore How To Listen For Changes To ONE Document

I just want to get notified whenever ONE document is changed or updated. Every example of getting updates is always using collections. I tried to implement that with only using one document and it never gets any updates. Here is what I have right now that doesn't work:

@override
Widget build(BuildContext context) {
StreamBuilder<DocumentSnapshot>(
    stream: Firestore.instance
        .collection("users")
        .document(widget.uid)
        .snapshots(),
    builder:
        (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
      user = snapshot.data.data as User;
    });

I've debugged this 100 times and it never gets to the "builder:" section. And this is not a problem with the document reference by the way. What am I doing wrong here?

like image 295
Jared Avatar asked Dec 31 '18 02:12

Jared


2 Answers

Here's an example

Firestore.instance
        .collection('Users')
        .document(widget.uid)
        .snapshots()
        .listen((DocumentSnapshot documentSnapshot) {

      Map<String, dynamic> firestoreInfo = documentSnapshot.data;

      setState(() {

        money = firestoreInfo['earnings'];

      });

    })
        .onError((e) => print(e));

but what you did wrong is here:

(BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
      user = snapshot.data.data as User;
    });

replace that with

(BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
      var firestoreData = snapshot.data;

      String info = firestoreData['info'];
    });
like image 139
Axes Grinds Avatar answered Sep 28 '22 05:09

Axes Grinds


This is my experience and working fine. (StreamBUilder with BLoC pattern).

Step1 => Filter by Query & limit

var userQuery = Firestore.instance
          .collection('tbl_users')
          .where('id', isEqualTo: id)
          .limit(1);

Step2 => Listening

userQuery.snapshots().listen((data) {
            data.documentChanges.forEach((change) {
              print('documentChanges ${change.document.data}');
            });
          });

BLoC

class HomeBloc {
  final userSc = StreamController<UserEntity>(); 

  Future doGetProfileFireStore() async {
    await SharedPreferencesHelper.getUserId().then((id) async {
      print('$this SharedPreferencesHelper.getUserId() ${id}');
      var userQuery = Firestore.instance
          .collection('tbl_users')
          .where('id', isEqualTo: id)
          .limit(1);
      await userQuery.getDocuments().then((data) {
        print('$this userQuery.getDocuments()');
        if (data.documents.length > 0) {
          print('$this data found');
          userQuery.snapshots().listen((data) {
            data.documentChanges.forEach((change) {
              print('documentChanges ${change.document.data}');
              userSc.sink.add(new UserEntity.fromSnapshot(data.documents[0]));
            });
          });
        } else {
          print('$this data not found');
        }
      });
    });
  }

  void dispose() {
    userSc.close();
  } 
}

View

new StreamBuilder(
        stream: bloc.userSc.stream,
        builder: (BuildContext context, AsyncSnapshot<UserEntity> user) {
          return new Center(
            child: new Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                user.hasData
                    ? new Container(
                        width: 80,
                        height: 80,
                        decoration: new BoxDecoration(
                          borderRadius: BorderRadius.circular(100.0),
                          image: new DecorationImage(
                            image: NetworkImage(user.data.photo),
                            fit: BoxFit.cover,
                          ),
                        ),
                      )
                    : new Container(
                        width: 50,
                        height: 50,
                        child: new CircularProgressIndicator(
                          strokeWidth: 2,
                          valueColor:
                              AlwaysStoppedAnimation<Color>(ColorsConst.base),
                        ),
                      ),
                new Container(
                  margin: EdgeInsets.fromLTRB(10, 0, 0, 0),
                  child: new Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    crossAxisAlignment: CrossAxisAlignment.center,
                    children: <Widget>[
                      new Text(
                        user.hasData
                            ? '${user.data.username.toUpperCase()}'
                            : 'loading',
                        style: TextStyleConst.b16(
                            color: Colors.black
                                .withOpacity(user.hasData ? 1.0 : 0.2),
                            letterSpacing: 2),
                      ),
                      new Container(
                        margin: EdgeInsets.all(5),
                      ),
                      new Text(
                        user.hasData ? '${user.data.bio}' : 'loading',
                        style: TextStyleConst.n14(
                            color: Colors.black
                                .withOpacity(user.hasData ? 1.0 : 0.2)),
                      ),
                      new Container(
                        margin: EdgeInsets.fromLTRB(0, 10, 0, 0),
                        padding: EdgeInsets.all(10),
                        decoration: new BoxDecoration(
                          color: Colors.blue,
                          borderRadius: BorderRadius.circular(100.0),
                        ),
                        child: new Row(
                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
                          children: <Widget>[
                            new Row(
                              children: <Widget>[
                                new Icon(
                                  Icons.trending_up,
                                  color: Colors.white,
                                  size: 20,
                                ),
                                new Text(
                                  '145K',
                                  style:
                                      TextStyleConst.b14(color: Colors.white),
                                ),
                              ],
                            ),
                            new Container(
                              margin: EdgeInsets.fromLTRB(10, 0, 10, 0),
                            ),
                            new Row(
                              children: <Widget>[
                                new Icon(
                                  Icons.trending_down,
                                  color: Colors.white,
                                  size: 20,
                                ),
                                new Text(
                                  '17',
                                  style:
                                      TextStyleConst.b14(color: Colors.white),
                                ),
                              ],
                            ),
                          ],
                        ),
                      ),
                    ],
                  ),
                ),
              ],
            ),
          );
        },
      ),
like image 42
OpannapO Avatar answered Sep 28 '22 03:09

OpannapO