Объединение нескольких запросов в один список с нумерацией страниц - PullRequest
0 голосов
/ 02 апреля 2019

Я создаю продукт типа социальной сети, в котором у пользователей есть подписчики и "workout_posts".Я создал модель, аналогичную описанной Алексом Мамо в этом ответе на Firestore - как структурировать канал и следовать системе .

У меня есть коллекция пользователей, коллекция подписчиков и коллекция сообщений о тренировках.

Я эффективно настроил запрос для отображения всех однопользовательских сообщений через пагинацию со следующим кодом.Это отлично подойдет для отображения всех сообщений одного пользователя в представлении профиля приложения.

class Workouts extends StatefulWidget {
  Workouts({Key key, this.user}) : super(key: key);

  final User user;

  @override
  _WorkoutsState createState() => new _WorkoutsState(
      user: user
  );
}

class _WorkoutsState extends State<Workouts> {

  _WorkoutsState({this.user});

  final User user;

  Firestore _firestore = Firestore.instance;
  List<DocumentSnapshot> _workouts = [];
  bool _loadingWorkouts = true;
  int _per_page = 8;
  DocumentSnapshot _lastWorkout;
  ScrollController _scrollController = ScrollController();
  bool _gettingMoreWorkouts = false;
  bool _moreWorkoutsAvailable = true;


  _getWorkouts() async {

    Query q = _firestore
        .collection('workouts_posts')
        .document(user.user_id)
        .collection('posts')
        .orderBy("post")
        .limit(_per_page);

    setState(() {
      _loadingWorkouts = true;
    });

    QuerySnapshot querySnapshot = await q.getDocuments();
    _workouts = querySnapshot.documents;
    _lastWorkout = querySnapshot.documents[querySnapshot.documents.length - 1];

    setState(() {
      _loadingWorkouts = false;
    });
  }

  _getMoreProducts() async {
    print("get more products called");

    if (_moreWorkoutsAvailable == false) {
      return;
    }

    if (_gettingMoreWorkouts == true) {
      return;
    }

    _gettingMoreWorkouts = true;

    Query q = _firestore
        .collection('workouts_posts')
        .document(user.user_id)
        .collection('posts')
        .orderBy("post")
        .startAfter([_lastWorkout.data['post']]).limit(_per_page);

    QuerySnapshot querySnapshot = await q.getDocuments();

    if (querySnapshot.documents.length < _per_page) {
      _moreWorkoutsAvailable = false;
    }

    _lastWorkout = querySnapshot.documents[querySnapshot.documents.length - 1];
    _workouts.addAll(querySnapshot.documents);

    setState(() {});

    _gettingMoreWorkouts = false;
  }

  @override
  void initState() {
    super.initState();
    _getWorkouts();
    _scrollController.addListener(() {
      double maxScroll = _scrollController.position.maxScrollExtent;
      double currentScroll = _scrollController.position.pixels;
      double delta = MediaQuery.of(context).size.height * 0.25;

      if (maxScroll - currentScroll < delta) {
        _getMoreProducts();
      }
    });
  }
  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        new Expanded(
          child: _loadingWorkouts == true
              ? Container(
            child: Center(
              child: Text("Loading..."),
            ),
          )
              : Container(
            child: Center(
              child: _workouts.length == 0
                  ? Center(
                child: Text("No Workouts to show"),
              )
                  : ListView.builder(
                  controller: _scrollController,
                  itemCount: _workouts.length,
                  itemBuilder: (BuildContext ctx, int index) {
                    return new PostWidget(
                      postText: _workouts[index].data['post'],
                      pictureURL: _workouts[index].data['url'],
                      goalText: _workouts[index].data['goalText'],
                      userOfPost: _workouts[index].data['user'],
                      currentUser: user,
                      goalType: "workouts",
                      postID: _workouts[index].documentID,
                    );
                  }),
            ),
          ),
        )
      ],
    );
  }

}

Моя задача состоит в том, чтобы запросить сообщения всех подписчиков для каждого пользователя, объединить их в один список, а затем отсортировать по отметке времени - все при сохранении нумерации страниц.У кого-нибудь есть опыт или совет по подходу?Должен ли я изменить свою модель данных, чтобы денормализовать ее?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...