即使流正在返回对象,Flutter StreamProvider 也会返回 null 对象

Posted

技术标签:

【中文标题】即使流正在返回对象,Flutter StreamProvider 也会返回 null 对象【英文标题】:Flutter StreamProvider returns null object eventhough stream is returning objects 【发布时间】:2020-08-17 02:20:27 【问题描述】:
    import 'package:flutter/material.dart';
    import 'package:cloud_firestore/cloud_firestore.dart';
    import 'package:provider/provider.dart';
    import 'package:collection/collection.dart';

    void main() => runApp(MyApp());

    class MyApp extends StatelessWidget 
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) 
        var _db = FirestoreService();
        return MultiProvider(
          providers: [
            StreamProvider(create:(context)=>_db.getItems(),
              catchError:(BuildContext context,e)
              print("Error:$e");
              return null;
              ,
              updateShouldNotify:const ListEquality<Item>().equals),
          ],

          child: MaterialApp(
            title: 'Flutter Demo',
            theme: ThemeData(
              primarySwatch: Colors.blue,
            ),
            home: Catalog(),
          ),
        );
      
    

    class Item
      String name;
      double price;

      Item(this.name,this.price);

      Item.fromJSON(Map<String,dynamic> json)
      :name=json['name'],
      price=json['price'];

      factory Item.fromMap(Map data)
      
        return Item(name: data['name'],price:data['price']);
      

    
    class FirestoreService

      var _db = Firestore.instance;

      Stream<List<Item>> getItems()
      
        return _db.collection('akurdi')
            .snapshots()
            .map((snapshot)=>snapshot.documents
            .map((document)=>Item.fromMap(document.data)).toList());
      

    

    class Catalog extends StatelessWidget 
      @override
      Widget build(BuildContext context) 

        var items = Provider.of<List<Item>>(context);

        print(items.length);

        return ListView.builder(
          itemCount: items.length,
          itemBuilder: (context,index)
              return ListTile(
              title: Text(items[index].name),
              trailing: Text(items[index].price.toString())
              );
          ,
        );
      
    

错误:

I/flutter (12444):在 null 上调用了 getter 'length'。

I/flutter (12444):接收器:null

I/flutter (12444):尝试调用:长度

当我特别调试代码时 getItems() 函数, 我看到了 firestore 数据库中的实际值,但是当我使用提供程序时

var items = Provider.of>(上下文) 要获取值,它会返回 null。

【问题讨论】:

您可以在删除以下行后尝试。 updateShouldNotify:const ListEquality().equals?出错后是否显示数据?因为最初由于出现该错误,因此流中没有数据。 是的,最初我没有使用 Updateshouldnotify ,但它仍然没有工作 数据报错后是否显示?因为最初由于出现该错误,因此流中没有数据。 没有数据显示,它只是返回调用列表生成器的错误将长度为0(null) 是否有必要提供初始数据,因为在我的情况下,每当第一次构建应用程序时,它都会调用流提供程序并请求 List 流,这将进一步调用调用到firestore数据库,所以我认为它将使用从流中接收到的数据进行初始化 【参考方案1】:

我认为 updateShouldNotify 是这里真正的问题。在该条件不成立之前,数据不会改变。

只需删除该 updateShouldNotify 即可。

当您想控制何时必须更改数据时,您可以使用它。例如添加或删除任何新数据,然后您可以比较以前和当前的数据长度并相应地更新。

【讨论】:

以上是关于即使流正在返回对象,Flutter StreamProvider 也会返回 null 对象的主要内容,如果未能解决你的问题,请参考以下文章

Flutter 流:流生成器返回 Null 值

如何在 Flutter 中管理对象列表流?

Flutter / Dart / Firebase - 流返回空列表

如何在 Flutter 小部件测试中等待未来完成?

使用流在 Flutter 中不起作用检查身份验证状态

Dart/Flutter POST 请求和流响应