How to use Flutter (web app) stream builder with Firestore
Solution 1
I had the same issue when I tried to create a web version of my flutter mobile app which uses a lot of StreamBuilders
. The following works for me:
Pubspec.yaml dependencies:
firebase_web: ^5.0.9
firebase_core: ^0.4.3+2
In your code:
import 'package:firebase_web/firestore.dart';
import 'package:firebase_web/firebase.dart';
body: new StreamBuilder(
stream: firestore().collection('collection').onSnapshot,
builder: (context, snapshot) {
...
Below I have included a list with changes that I encountered so far going from a flutter mobile app to a flutter web app:
documents
=docs
as insnapshot.data.docs.length
documents()
=doc()
as infirestore().collection('foo').doc('bar')
reference
=ref
as insnapshot.ref
data
=data()
as insnapshot.data()
- The method
setData
from Firestore =set
- The method
updateData
from Firestore =update(data:{'yourKey': 'yourValue',})
Hope this can help!
Solution 2
The querySnapshot.docs
property returns a List<DocumentSnapshot>
, while you need a stream
for the stream
property where each item on the stream is a list.
I've only needed this with the FlutterFire libraries for iOS/Android, but it should look something like this:
Stream<List<DocumentSnapshot>> getStream() async* {
fb.firestore().collection("MyCollection").onSnapshot.listen((querySnapshot) {
yield querySnapshot.docs;
}
}
danh
Updated on December 15, 2022Comments
-
danh over 1 year
I see several questions and answers about Flutter for mobile that use stream builder like this:
body: new StreamBuilder( stream: Firestore.instance.collection("collection").snapshots(), builder: (context, snapshot) { ...
I'm trying to do the same on flutter for the web, but in my configuration, the
snapshots()
method is unknown, generating an exception while running (and a vscode warning beforehand). Why? Do I have an incorrect setup?I've followed these steps which I found here and elsewhere:
1) Included firebase as a dependency in pubspec.yaml
dependencies: flutter: sdk: flutter firebase: ^6.0.0
2) Included the firestore js scripts in the index.html body tag:
<script src="https://www.gstatic.com/firebasejs/7.5.0/firebase-app.js"></script> <script src="https://www.gstatic.com/firebasejs/7.5.0/firebase-analytics.js"></script> <script src="https://www.gstatic.com/firebasejs/7.5.0/firebase-firestore.js"></script> <script src="main.dart.js" type="application/javascript"></script>
3) In main.dart, imported firebase.dart files (using advice given here, though I'm not exactly sure which step above got me access to this package. I'm a flutter nube, if it isn't obvious)
import 'package:flutter/material.dart'; import 'package:firebase/firebase.dart' as fb; import 'package:firebase/firestore.dart' as fs;
Having followed these steps, I can get this code working....
void main() { if (fb.apps.length == 0) { try { fb.initializeApp( apiKey: "mike", authDomain: "myauthdomain", databaseURL: "mydburl", projectId: "myproductid", storageBucket: "mystoragebucket", ); } catch(e) { print(e); } } fs.Firestore store = fb.firestore(); fs.CollectionReference ref = store.collection("MyCollection"); ref.onSnapshot.listen((querySnapshot) { querySnapshot.docs.forEach((doc) { print(doc.data()); // this works!! }); }); runApp(MyApp()); }
But, as I mentioned earlier, getting the stream builder working, all of the advice suggests that I can get a stream of snapshots by saying...
class MyList extends StatelessWidget { @override Widget build(BuildContext context) { return new StreamBuilder( stream: fb.firestore().collection('MyCollection').snapshots(), ...
The packages I have running on web don't seem to have anything like the
snapshots
method (or property) on a firestore collection reference. Can somebody set me straight? -
danh over 4 yearsThanks. Can you think of a reason why I'm seeing "Error: 'yield' isn't a type." on
yield querySnapshot.docs();
? -
Frank van Puffelen over 4 yearsHmmm.... I was hoping this would work for you, as I use it in some of my own tests here: stackoverflow.com/a/59097364/209103
-
danh over 4 yearsI haven't actually tried this to see if it works, and I may not try it. I decided to abandon flutter for www until google actually (really) supports it. In the meantime, let's assume this works, and thanks.
-
Chris about 4 years@Lorence, I can't get your method to work... what am I doing wrong? I know how to do this with Firestore in regular flutter, I can't understand what I need to do
-
Chris about 4 yearsI want to use a Streambuilder to return a ListView.builder that return a list of widgets based on snapshot of documents in a collection...
-
Lorence Cramwinckel about 4 yearsHi @Chris if I understand correctly you want a streambuilder that returns a ListView.builder which returns widgets based on the snapshot. I put an example on github Check the code out here. Let me know if this is getting close to what you're looking for
-
Chris about 4 yearsHi Lorence, yes this is exactly what I'm trying to do. I understand the structure but the stream just isn't returning any data, or if it is it's not waiting for that data before the widget is built... So what I am getting is: "Something is wrong" .. no matter how I try to query, e.g.
if(snapshot.hasData){}
or whether I target a collection or document... -
Chris about 4 yearsFeel like I'm going mad... :(
-
Lorence Cramwinckel about 4 yearshm that is maddening indeed! What about your database rules? Do you have something like the following:
match /databases/{database}/documents { match /{document=**} { allow read, write: if true; }
Or what about your indexes? -
Chris about 4 yearsOmg.. I just switched it to true from false and now it's working... Thank you so much, I completely forgot about the database rules
-
Chris about 4 yearsHi again, I don't suppose you could help? I am able to target data by using a document as my stream but when using a collection I am unable to target info using the index... e.g.
stream: Firestore.instance.collection('collection').snapshots()
but when I try to dosnapshot.data
, I am unable to add.documents
or.docs
, and when I trysnapshot.data[index]['data']
I am not getting anything back... Also, I'm having problems with itemCount because I am getting a Future<int> back :( -
Lorence Cramwinckel about 4 yearshave you tried using
.onSnapshot
instead of.snapshots()
, so without the brackets? -
CiriousJoker over 3 yearsThis should work: Stream<...> stream = fb.firestore().collection("MyCollection").onSnapshot; await for (final snapshot in stream) { yield* snapshot.docs; } }