12

I'm trying to listen to changes in a single document of a collection, but I can't get it to work.

Widget build(BuildContext context) {
  return StreamBuilder(
    stream: Firestore.instance.collection("events").document(widget.documentID).get().asStream(),
    ...
  }
}

I'm using the .asStream() method, but I'm only getting the document once. If I change the data in the Firebase console, nothing updates unless I reopen the view.

Is there a way to do this?

creativecreatorormaybenot
  • 114,516
  • 58
  • 291
  • 402
Nauzet
  • 163
  • 3
  • 11

2 Answers2

15

The reason you are only getting the document once is because the DocumentReference.get method originally only returns a Future and using asStream will only return that one single Future to the Stream.

The cloud_firestore package, however, has a built-in method of listening to documents properly.
You can use DocumentReference.snapshots instead, which returns a Stream of every change of that document.

In your code, you will only have to replace .get().asStream() by .snapshots().

creativecreatorormaybenot
  • 114,516
  • 58
  • 291
  • 402
  • 3
    Great answer. I didn't even know `DocumentReference.snapshots()` existed, and it's great for this use-case. On other platforms you'll have to do a query on `FieldPath.documentId` as shown in Denys' answer here: https://stackoverflow.com/a/52252264 – Frank van Puffelen Jun 08 '19 at 19:22
1

if you want to get a single document use Future builder instead of Stream Builder.

FutureBuilder<DocumentSnapshot>(
                                              future: Firestore.instance
                                                  .collection('users')
                                                  .document(widget.puid)
                                                  .get(),
                                              builder: (context,
                                                  AsyncSnapshot<
                                                          DocumentSnapshot>
                                                      snapshot) {
                                                if (snapshot.hasError)
                                                  return Center(
                                                    child: Text(snapshot
                                                        .hasError
                                                        .toString()),
                                                  );
                                                return snapshot.hasData
                                                    ? Text(
                                                        "${snapshot.data['username']}",
                                                        style: TextStyle(
                                                            color:
                                                                kPrimaryColor,
                                                            fontSize: 18,
                                                            fontWeight:
                                                                FontWeight
                                                                    .bold),
                                                      )
                                                    : Container();
                                              },
                                            ),
gsm
  • 2,348
  • 17
  • 16