【问题标题】:Flutter StreamProvider returning null despite stream returning objects尽管流返回对象,但 Flutter StreamProvider 返回 null
【发布时间】:2020-07-25 04:04:15
【问题描述】:

我正在尝试设置一个个人资料类型页面,用户可以在其中查看他们的信息,最终我将添加功能,以便他们可以更改他们的数据。我正在使用 Provider 访问 Firebase 流 <User>,它返回当前用户的 UID(这工作正常)。然后使用 UID 访问他们的 <UserData> 流,但是当我尝试打印 UserData().email 或任何其他数据位时,它只会返回 null。代码如下:

class Profile extends StatefulWidget {
  @override
  _ProfileState createState() => _ProfileState();
}

class _ProfileState extends State<Profile> {
  @override
  Widget build(BuildContext context) {

    final user = Provider.of<User>(context);

    return StreamProvider<UserData>.value(
      initialData: UserData.initialData(),
      value: DatabaseService(uid: user.uid).userData,
      child: Scaffold(
        appBar: AppBar(),
        drawer: NavigationDrawer(),
        body: ListView(
          children: <Widget>[
            ListTile(
              title: Text(UserData().email),
            )
          ],
        ),
      ),
    );
  }
}

流本身如下所示:

  UserData _userDataFromSnapshot(DocumentSnapshot snapshot) {
    return UserData(
      uid: uid,
      email: snapshot.data['email'],
      firstName: snapshot.data['firstName'],
      lastName: snapshot.data['lastName'],
      phone: snapshot.data['phone'],
      dateCreated: snapshot.data['dataCreated'],
      isVerified: snapshot.data['isVerified']
    );
  }

  //User data stream
  Stream<UserData> get userData {
    return userDataCollection.document(uid).snapshots()
        .map(_userDataFromSnapshot);
  }

UserData 类就是这个

class UserData {

  final String uid;
  final String email;
  final String firstName;
  final String lastName;
  final String phone;
  final DateTime dateCreated;
  final bool isVerified;

  UserData({ this.uid, this.email, this.firstName, this.lastName, this.phone, this.dateCreated, this.isVerified });

  factory UserData.initialData() {
    return UserData(
      uid: '',
      email: '',
      firstName: '',
      lastName: '',
      phone: '',
      dateCreated: null,
      isVerified: null,
    );
  }
}

最后这是我从 ListTile 得到的错误,因为 UserData().email 为空,而不是字符串:

A non-null String must be provided to a Text widget.
'package:flutter/src/widgets/text.dart':
Failed assertion: line 285 pos 10: 'data != null'

我认为这可能是数据未及时加载的问题,因此当 Flutter 尝试构建页面时,数据不存在,但添加 UserData.initialData 似乎没有帮助。我已经设法使用 StreamBuilder 让它工作,但是我不知道是否使用这是最佳实践,或者我是否应该使用 Provider 做所有事情,所以任何帮助都将不胜感激。

谢谢

【问题讨论】:

    标签: firebase flutter dart flutter-dependencies flutter-provider


    【解决方案1】:

    我认为您以错误的方式使用了 StreamProvider。在以下代码中,您将创建一个新的 UserData 对象。

       ListTile(
              title: Text(UserData().email),
            )
    

    这是一个示例,您可以通过创建单独的小部件来使用 StreamProvider。

    class Profile extends StatefulWidget {
      @override
      _ProfileState createState() => _ProfileState();
    }
    
    class _ProfileState extends State<Profile> {
      @override
      Widget build(BuildContext context) {
    
        return StreamProvider<UserData>.value(
          initialData: UserData.initialData(),
          value: DatabaseService(uid: user.uid).userData,
          child: SecondWidget(),
        );
      }
    }
    
    class SecondWidget extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        final user = Provider.of<UserData>(context);
        return Scaffold(
          appBar: AppBar(),
          drawer: NavigationDrawer(),
          body: ListView(
            children: <Widget>[
              ListTile(
                title: Text(user.email),
              )
            ],
          ),
        );
      }
    }
    

    【讨论】:

    • 非常感谢,效果很好,虽然我只是在_ProfileState 中保留了final user = Provider.of&lt;User&gt;(context); 位,因为它提供了DatabaseService(uid: user.uid) 中所需的uid
    猜你喜欢
    • 2020-08-17
    • 2021-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-07
    • 2016-03-22
    • 1970-01-01
    • 2018-03-09
    相关资源
    最近更新 更多