简体   繁体   English

Flutter Firestore 如何监听一个文档的变化

[英]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.获取更新的每个示例始终使用 collections。我尝试仅使用一个文档来实现它,但它从未获得任何更新。 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.我已经调试了 100 次,但它从未进入“构建器:”部分。 And this is not a problem with the document reference by the way.顺便说一句,这不是文档引用的问题。 What am I doing wrong here?我在这里做错了什么?

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'];
    });

This is my experience and working fine.这是我的经验,工作正常。 ( StreamBUilder with BLoC pattern). (StreamBUilderBLOC图案)。

Step1 => Filter by Query & limit Step1 => 按查询和限制过滤

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

Step2 => Listening步骤 2 => 听力

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),
                                ),
                              ],
                            ),
                          ],
                        ),
                      ),
                    ],
                  ),
                ),
              ],
            ),
          );
        },
      ),
String collPath = 'books';
String docPath= 'auNEAjG276cQ1C9IUltJ';

DocumentReferance documentReferance = firestoreInstance.collection(collPath).document(docPath);

documentReference.snapshots().listen((snapshot) {
  print(snapshot.data);
}

Here's the solution that uses StreamBuilder :这是使用StreamBuilder的解决方案:

StreamBuilder(
        stream: Firestore.instance
            .collection("sightings")
            .doc(sighting.sightingID)
            .snapshots(),
        builder: (context, snapshot) {
          sighting = Sighting.fromMap(snapshot.data.data()); // Gives you the data map
          return Scaffold(
            appBar: AppBar(
              title: Text('Document Details'),
            ),
            body: Column(
                children: [
                  Text(sighting.type)
                ],
              ),
          );
        });

The key is the snapshot.data.data() line which returns the map of data from the document.关键是 snapshot.data.data() 行,它返回文档中的数据映射。

Update 2023 with null safety使用null safety更新 2023

 @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: StreamBuilder<DocumentSnapshot<Map<String, dynamic>>>(
          stream:  FirebaseFirestore
                   .instance
                   .collection('users')
                   .doc(widget.uid) 
                   // .doc(FirebaseAuth.instance.currentUser!.uid) // 👈 Use this if you want to listen to the present user's document
                   .snapshots(), 
          builder:
              (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
            if (snapshot.hasError) {
              return const Text('Something went wrong');
            }
            if (snapshot.connectionState == ConnectionState.waiting) {
              return const Text("Loading");
            }
            Map<String, dynamic> data =
                snapshot.data!.data()! as Map<String, dynamic>;
            return Text(data['fullName']); // 👈 your valid data here
          },
        ),
      ),
    );
  }

Also refer: How to use StreamBuilder and FutureBuilder for single and multiple documents另请参阅: How to use StreamBuilder and FutureBuilder for single and multiple documents

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Flutter firestore 如何一个一个地获取文档? - Flutter firestore how get document one by one? 如何用 ESP8266 监听 Firestore 的变化? - How to listen to changes in Firestore with ESP8266? 我可以听取 Firestore 文档中的单个值更改吗 - Can I listen to individual value changes in a Firestore Document 监听 Firestore 上的文档更改并为 StreamBuilder 创建对象的 stream - Listen to document changes on Firestore and create a stream of objects for StreamBuilder 当我在 flutter firestore 中打开互联网时,我如何知道我在离线模式下对文档所做的所有更改都同步到了 firestore - How do i know all my changes made to document in offline mode are synced to firestore when i turn on internet in flutter firestore Flutter Firestore 如何将文档内容转换为流 - Flutter Firestore how to convert document content to stream 如何使用 Flutter 在 FireStore 的集合中创建文档 - How to create document in collection in FireStore with Flutter 您如何根据查询侦听 Firestore 集合中的更改? - How do you listen for changes in a Firestore collection based on a query? 如何遍历 Flutter 中的 Firestore 文档中的字段? - How to iterate through fields in a Firestore Document in Flutter? 无法从 flutter Cloud firestore 获取一份文件 - Can't get one document from flutter cloud firestore
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM