2
votes

I am trying to achieve a functionality where the app displays all the users' details in a grid view except the current user's. I have been trying to assign snapshots to _stream and then apply the _stream value in StreamBuilder(). But it throws an error instead.

Database _database = Database();
Stream _stream;
String currentUserId;

@override
void initState() {
    getCurrentUserId(); //currentUserId gets its value here
    getAllUsers();
    super.initState();
}

getAllUsers() async {


 Stream<QuerySnapshot> snapshots = await _database.getAllUsers();
    
 _stream = snapshots.map((querySnapshot) => querySnapshot.documents.where((documentSnapshot)
          => documentSnapshot.data["userId"] != currentUserId
  ).toList())
}

//..

StreamBuilder(
stream: _stream,
builder: (context, snapshot) {
 if (snapshot.data != null)
 //..
 
}
//..
)

NEW: if I add as QuerySnapshot, the snapshot in the StreamBuilder will be null instead of throwing an exception.

// NEW
     _stream = snapshots.map((querySnapshot) => querySnapshot.documents.where((documentSnapshot)
     => documentSnapshot.data["userId"] != currentUserId
     ).toList() as QuerySnapshot);

Database class

getAllUsers() async {
    return await _firestore.collection("users").snapshots();
}

Exception

════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following NoSuchMethodError was thrown building StreamBuilder<dynamic>(dirty, state: _StreamBuilderBaseState<dynamic, AsyncSnapshot<dynamic>>#6e31f):
Class 'List<DocumentSnapshot>' has no instance getter 'documents'.
Receiver: Instance(length:2) of '_GrowableList'
Tried calling: documents

The relevant error-causing widget was: 
  StreamBuilder<dynamic> file:///Users/suriantosurianto/AndroidStudioProjects/apui/lib/fragments/home_fragment.dart:66:12
When the exception was thrown, this was the stack: 
#0      Object.noSuchMethod (dart:core-patch/object_patch.dart:53:5)
#1      _HomeFragmentState.build.<anonymous closure> (package:apui/fragments/home_fragment.dart:80:42)
#2      StreamBuilder.build (package:flutter/src/widgets/async.dart:509:81)
#3      _StreamBuilderBaseState.build (package:flutter/src/widgets/async.dart:127:48)
#4      StatefulElement.build (package:flutter/src/widgets/framework.dart:4619:28)
...
════════════════════════════════════════════════════════════════════════════════════════════════════
3
The error is telling you that querySnapshot is a List<QuerySnapshot>, not a QuerySnapshot. So, you have to treat it like a list. - Doug Stevenson
can you elaborate it a bit? - hypergogeta

3 Answers

0
votes

We do not know which line is this error pointing, however if I understand correctly the reason might be type of StreamBuilder property stream that should be of Stream class (reference).

Seems _stream is a list created from stream using toList method (reference). I would try to remove this toList method, and see what will happen.

I hope it will help!

0
votes
// NEW
     _stream = snapshots.map((querySnapshot) => querySnapshot.documents.where((documentSnapshot)
     => documentSnapshot.data["userId"] != currentUserId
     ).toList() as QuerySnapshot);

here the querySnapshot is a List<DocumentSnapshot>!!!

you are probably have to use querySnapshot.where()

0
votes

As others point out, querySnapshot is a List<DocumentSnapshot> and not DocumentSnapshot, so you can't use the getter .documents(that getter is for DocumentSnapshot only, not for a List), This is becasue is retrieving the DocumentSnapshot of every user except the current user (a DocumentSnapshot for each user, so a List<DocumentSnapshot>).

If you want to return a Stream of type of List<DocumentSnapshot> then

_stream = snapshots
    .map<List<DocumentSnapshot>>((querySnapshot) => 
       querySnapshot.where((documentSnapshot) => 
          documentSnapshot.data["userId"] != currentUserId)
 );