Flutter StreamProvider возвращает ноль, несмотря на то, что поток возвращает объекты - PullRequest
0 голосов
/ 12 апреля 2020

Я пытаюсь настроить страницу типа профиля, где пользователи могут просматривать свою информацию, и в конечном итоге я добавлю функции, чтобы они могли изменять свои данные. Я использую провайдера для доступа к потоку Firebase <User>, который возвращает UID текущего пользователя (это работает нормально). Затем UID используется для доступа к их потоку <UserData>, но когда я пытаюсь напечатать UserData().email или любые другие биты данных, он просто возвращает ноль. Код выглядит следующим образом:

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, однако я не знаю, является ли это наилучшим практическим приемом, или я должен просто делать все с провайдером, чтобы можно было оценить любую помощь.

Спасибо

1 Ответ

1 голос
/ 12 апреля 2020

Я думаю, что вы неправильно использовали 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),
          )
        ],
      ),
    );
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...