Используйте StreamBuilder для отображения данных для текущего пользователя (не всех данных пользователей) из Firestore - PullRequest
0 голосов
/ 01 апреля 2020

Я пытаюсь использовать StreamBuilder во флаттере, чтобы вернуть список, но только для текущего пользователя, вошедшего в систему. Когда я пытался

StreamBuilder<QuerySnapshot>(
    stream:  _firestore.collection('meals').where('email', isEqualTo: loggedInUser.email).orderBy('date', descending: true).snapshots(),

, я получаю следующую ошибку:

Получатель 'email' был вызван на нуль.

Получатель: ноль

Пробный вызов: электронная почта

Работает нормально, когда я беру .where часть, но затем он просто возвращает все данные от каждого отдельного пользователя, и я только хочу, чтобы он возвращал данные, связанные с этим текущим пользователем.

Любые идеи были бы действительно полезны, поэтому спасибо заранее.

Джейсон

РЕДАКТИРОВАТЬ: Вот еще немного кода для немного больше контекста:

import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/widgets.dart';
import 'package:intl/intl.dart';
import 'package:less_food/utilities/add_edit_meal_log.dart';
import 'package:less_food/utilities/constants.dart';

final _firestore = Firestore.instance;
FirebaseUser loggedInUser;

class MealLog extends StatefulWidget {

  @override
  _MealLogState createState() => _MealLogState();
}

class _MealLogState extends State<MealLog> {
  final _auth = FirebaseAuth.instance;
  FirebaseUser loggedInUser;

  @override
  void initState() {
    super.initState();

    getCurrentUser();
  }

  void getCurrentUser() async {
    try {
      FirebaseUser user = await _auth.currentUser();
      if (user != null) {
        setState(() {
          loggedInUser = user;
          print('this is:  ${loggedInUser.email}');
        });
      }
    } catch (e) {
      print(e);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            MealsStream(),
          ],
        ),
      ),
    );
  }
}

class MealsStream extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<QuerySnapshot>(
    stream:  _firestore.collection('meals').where('email', isEqualTo: loggedInUser.email).orderBy('date', descending: true).snapshots(), 
      builder: (context, snapshot) {
        if (!snapshot.hasData) {
          return Center(
            child: CircularProgressIndicator(
              backgroundColor: Colors.lightBlueAccent,
            ),
          );
        }
        final meals = snapshot.data.documents.reversed;
        List<MealBubble> mealBubbles = [];
        for (var meal in meals) {
          final mealDate = meal.data['date'].toDate();
          print(DateFormat('dd-MM-yyyy').format(mealDate));
          final mealSelection = meal.data['mealSelection'];
          final mealDietChoice = meal.data['dietChoice'];

          final mealBubble = MealBubble(
            date: mealDate,
            selection: mealSelection,
            dietChoice: mealDietChoice,
          );

          mealBubbles.add(mealBubble);
        }
        return Expanded(
          child: ListView(
            reverse: false,
            padding: EdgeInsets.symmetric(vertical: 20.0),
            children: mealBubbles,
          ),
        );
      },
    );
  }
}

class MealBubble extends StatelessWidget {
  MealBubble({this.date, this.selection, this.dietChoice});

  final DateTime date;
  final String selection;
  final String dietChoice;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.all(10.0),
      child: Container(
        color: Colors.white,
        child: Column(
          children: <Widget>[
            Material(
              borderRadius: BorderRadius.circular(10.0),
              elevation: 5.0,
              color: Colors.lightBlueAccent,
              child: Padding(
                padding: EdgeInsets.symmetric(horizontal: 5.0),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceAround,
                  children: <Widget>[
                    Padding(
                      padding: const EdgeInsets.symmetric(horizontal: 13.0),
                      child: Text(
                        '${DateFormat('dd-MM-yyyy').format(date)}',
                        style: TextStyle(
                          color: Colors.white,
                          fontSize: 15.0,
                        ),
                      ),
                    ),
                    Text(
                      selection,
                      textAlign: TextAlign.start,
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 15.0,
                      ),
                    ),
                    SizedBox(
                      width: 2.0,
                    ),
                    Text(
                      dietChoice,
                      textAlign: TextAlign.start,
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 15.0,
                      ),
                    ),
                    ButtonTheme(
                      materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
                      minWidth: 0,
                      child: FlatButton(
                        child: Text(
                          'Edit',
                          style: kMealLogEditButtonTextStyle,
                        ),
                        onPressed: () {
                          showModalBottomSheet(
                            context: context,
                            builder: (context) => AddEditMealLog(),
                            isScrollControlled: true,
                          );
                        },
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}


1 Ответ

0 голосов
/ 02 апреля 2020

Проблема в том, что ваша глобальная переменная loggedInUser никогда не инициализируется. Тем не менее, у вас есть другая переменная с точно таким же именем, инициализируемая в другом классе, и я думаю, что это может вызвать у вас путаницу.

Как вы можете видеть, вы объявляете два объекта FirebaseUser с именем loggedInUser, один с областью действия файла (он существует глобально в файле), а другой внутри класса, то есть с областью действия класса (он существует только внутри этого класса!). Когда вы инициализируете loggedInUser в функции _MealLongState.getCurrentUser(), вы используете переменную класса, а не глобальную. Затем, когда вы обращаетесь к loggedInUser из метода MealsStream.build(), вы получаете глобальную переменную, которая не была инициализирована.

Решение состоит в том, чтобы удалить объявление переменной loggedInUser изнутри класс _MealLogState.

...