Flutter:即使在包含数据的情况下,StreamProvider也会在列表上返回null

时间:2020-06-12 11:20:49

标签: flutter dart google-cloud-firestore

我正在尝试在Firestore服务器和我的应用之间建立流。我正在尝试从服务器检索笔记列表以显示在ListView小部件中。但是,我一直收到一条错误消息,说正在返回的列表为空。通过调试,我注意到快照实际上确实包含我要访问的数据,因此在_notesFromSnapshot函数能够将每个快照映射到Note对象之前发生了一些错误。我认为该应用程序会在Stream有足够的时间来获取所有数据之前呈现ListView

编辑:如果我将StreamProvider更改为侦听QuerySnapshot而不是注释列表,则该列表有效,但是我需要方便的访问自定义对象。

NoteListScreen.dart

class NoteListScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final user = Provider.of<User>(context);

    return Scaffold(
      appBar: NavBar(title: 'My notes'),
      body: StreamProvider<List<Note>>.value(
        value: DatabaseService(uid: user.uid).notes,
        child: NoteList(),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Navigator.of(context).pushNamed('/note/create');
        },
        child: Icon(Icons.add),
      ),
    );
  }
}

NoteList.dart

class NoteList extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _NoteListState();
}

class _NoteListStateextends State<NoteList> {
  @override
  Widget build(BuildContext context) {
    final notes = Provider.of<List<Note>>(context);

    return ListView.builder(
            itemCount: notes.length,
                       ^^^^^^^^^^^^ Returns error: 'The getter 'length' was called on null.'

            itemBuilder: (context, index) {
              return Card(
                child: NoteItem(
                  name: notes[index].name,
                ),
              );
            },
          );
  }
}

DatabaseService.dart

class DatabaseService {
  final String uid;

  DatabaseService({this.uid});

  // collection reference
  final CollectionReference _userCollection = Firestore.instance.collection('users');

  .....

  List<Note> _notesFromSnapshot(QuerySnapshot snapshot) {
    return snapshot.documents.map((doc) {
      return Note(
        name: doc.data['name'],
      );
    });
  }

  Stream<List<Note>> get notes {
    return _userCollection
        .document(uid)
        .collection('notes')
        .snapshots()
        .map(_notesFromSnapshot);
  }
}

1 个答案:

答案 0 :(得分:0)

我通过在此函数末尾添加.toList()来解决此问题:

List<Note> _notesFromSnapshot(QuerySnapshot snapshot) {
    return snapshot.documents.map((doc) {
      return Note(
        name: doc.data['name'],
      );
    }).toList();
  }