首页 > 解决方案 > Flutter:即使包含数据,StreamProvider 也会在列表中返回 null

问题描述

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

编辑:如果我将 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,
                ),
              );
            },
          );
  }
}

数据库服务.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);
  }
}

标签: flutterdartgoogle-cloud-firestore

解决方案


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

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

推荐阅读