【问题标题】:How to fetch all documents from a firebase collection in Flutter using the Riverpod package?如何使用 Riverpod 包从 Flutter 中的 firebase 集合中获取所有文档?
【发布时间】:2020-10-22 10:48:45
【问题描述】:

我正在使用提供程序包,并且有一个提供程序从全局变量idea 中获取其初始值,该全局变量idea 是一个json 数据列表,类型为List>。

下面是代码,它可以正常工作。

final ideasListProvider = StateNotifierProvider<IdeaList>((ref) {
  return IdeaList([for (var i in ideas) Idea.fromJson(i)]);
});

现在我想要实现的是替换变量 idea,而是使用我从 firebase 上的集合中获得的文档列表。

但我不知道如何从这里开始。

这是第二个从 firestore 中获取快照的提供程序。

final firbaseIdeaProvider = StreamProvider.autoDispose((ref) {
  return FirebaseFirestore.instance.collection('ideas').snapshots();
});

我现在该怎么办? 我的其余代码依赖于ideasListProvider,因此我必须以某种方式为其提供来自firebase 上的ideas 集合的文档列表。

【问题讨论】:

    标签: firebase flutter google-cloud-firestore riverpod


    【解决方案1】:

    好消息,您走在正确的轨道上。首先,您想要做的可能是将您的 Firestore 数据映射到您的数据模型。这可以通过创建从您的 Firestore 数据流映射的新流来完成:

    final firebaseIdeaProvider = StreamProvider.autoDispose<List<Idea>>((ref) {
      final stream = FirebaseFirestore.instance.collection('ideas').snapshots();
      return stream.map((snapshot) => snapshot.docs.map((doc) => Idea.fromJson(doc.data())).toList());
    });
    

    现在剩下的就是读取您的 StreamProvider。处理加载、错误和新数据状态的示例如下(使用hooks_riverpod):

    class IdeasExample extends HookWidget {
      const IdeasExample({Key key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Ideas Example'),
          ),
          body: useProvider(firebaseIdeaProvider).when(
            loading: () => const Center(child: CircularProgressIndicator()),
            error: (err, stack) => Center(child: Text(err.toString())),
            data: (ideas) {
              return ListView.builder(
                itemCount: ideas.length,
                itemBuilder: (_, index) {
                  return ListTile(
                    title: Text(ideas[index].toString()),
                  );
                },
              );
            },
          ),
        );
      }
    }
    

    没有钩子:

    class IdeasExample extends ConsumerWidget {
      const IdeasExample({Key key}) : super(key: key);
    
      @override
      Widget build(BuildContext context, ScopedReader watch) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Ideas Example'),
          ),
          body: watch(firebaseIdeaProvider).when(
            loading: () => const Center(child: CircularProgressIndicator()),
            error: (err, stack) => Center(child: Text(err.toString())),
            data: (ideas) {
              return ListView.builder(
                itemCount: ideas.length,
                itemBuilder: (_, index) {
                  return ListTile(
                    title: Text(ideas[index].toString()),
                  );
                },
              );
            },
          ),
        );
      }
    }
    

    【讨论】:

    • 您好,谢谢您的回复。我试过了,但它触发了异常[core/no-app] No Firebase App '[DEFAULT]' has been created - call Firebase.initializeApp() 但问题是我已经在 mian.dart 文件中初始化了 Firestore。任何想法可能是什么原因造成的?
    • 您是否正确地等待它? Future&lt;void&gt; main() async { await Firebase.initializeApp(); ... }
    • 原来我确实忘记在 Firebase.initializeApp() 之前添加等待。该代码现在可以正常工作。如果你能帮我做最后一个,我也想在另一个提供者中使用这个值,这个是具体的。final ideasListProvider = StateNotifierProvider&lt;IdeaList&gt;((ref) { return IdeaList([for (var i in ideas) Idea.fromJson(i)]); }); 但是在 IdeaList 中返回[for (var i in ideas) Idea.fromJson(i)],我想返回我们收到的列表来自 firebaseIdeaProvider。有没有可能做到这一点?
    • 这是可能的,尽管我对您为什么要这样做有点困惑。我认为通过简单地在 Firestore 中更新您的 Ideas 可能有更简单的方法来完成您想要做的任何事情,并且流将提供最新的值,而不是在 StateNotifier 中本地操作它们.
    • 我希望能够在用户使用枚举单击按钮时过滤想法列表。在实施 firebase 之前,我正在查看 ideaProvider 的状态和不同提供者中的枚举,并基于此显示项目。所以想知道是否可以使用我从 ideaFirebaseProvider 获得的值以某种方式完成?
    猜你喜欢
    • 2021-01-06
    • 2021-07-29
    • 1970-01-01
    • 2022-01-18
    • 2020-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多