Как объединить два запроса в Firestore и отсортировать их по времени

Когда я работаю над своим приложением flutter, я столкнулся с проблемой, результат, который я хочу получить, - это отсортировать данные потока из разных коллекций по времени их публикации, например:

Представьте, что вы используете WhatsApp, и приложение позволяет отправлять сообщения, а также изображения или ваши голоса, верно? Но затем все они были перенесены на один экран и отсортированы по времени, хотя это разные типы данных, и мой случай похож на этот, это эффект, который я хочу использовать в своем приложении.

И я действительно понятия не имею, как решить эту проблему, а также удивлен, что я не могу найти никаких полезных ответов от Stack Overflow, впервые!

** Вот код, который может описать то, что я хочу:

Почтовый класс: **

 class Post {
 // Just proving that Post and Message has some same fields and some different fields

  const Post({
    required this.sender,
    required this.likes,
    required this.sentTime,
  });

  final Timestamp sentTime;
  final String sender;
  final int likes;
}

Класс сообщения:

class Message {
      const Message({
     required this.text, 
     required this.sender, 
     required this.sentTime,
   });
    
      final String text;
      final String sender;
      final Timestamp sentTime;
    }

Элемент публикации (виджет для публикации):

  class PostItem extends StatelessWidget {
      // Just to prove that a Post also has different UI compare to a Message
      const PostItem({required this.post});
    
      final Post post;
    
      @override
      Widget build(BuildContext context) {
        return Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Text(post.sentTime.toString()),
            Text('${post.likes} likes'),
          ],
        );
      }
    }

MessageItem (виджет для сообщения):

class MessageItem extends StatelessWidget {
  const MessageItem({required this.text});

  final String text;

  @override
  Widget build(BuildContext context) {
    return Text(text);
  }
}

И, наконец, наше тело прямо здесь:

 body: StreamBuilder(
        stream: FirebaseFirestore.instance
            .collection('Posts')
            .orderBy('sentTime', descending: true)
            .snapshots(),
        builder: (context, AsyncSnapshot<QuerySnapshot> postsSnap) {
          return StreamBuilder(
            stream: FirebaseFirestore.instance
                .collection('Messages')
                .orderBy('sentTime', descending: true)
                .snapshots(),
            builder: (context, AsyncSnapshot<QuerySnapshot> messageSnap) {
              final posts = postsSnap.data!.docs
                  .map(
                    (e) => Post(
                      sender: e.get('sender'),
                      likes: e.get('likes'),
                      sentTime: e.get('sentTime'),
                    ),
                  )
                  .toList();

              final messages = messageSnap.data!.docs
                  .map(
                    (e) => Message(
                      text: e.get('text'),
                      sender: e.get('sender'),
                      sentTime: e.get('sentTime'),
                    ),
                  )
                  .toList();

              // Now we got posts and messages that are ordered by time in their own collection,
              // but the challenge is we need to put those two lists together,
              // and order by time again, this time we mixed them.

              /// And lets assume that we got that mixed list =>
              /// final contents = The thing we wanted (mixedList);

              return ListView.builder(
                itemBuilder: (context, index) =>

                    // I MIGHT EXPECT: =>
                    /* 
                      if (contents[index] == a message) {
                        return MessageItem(text: contents[index].text);
                      } else {
                        return PostItem(post: contents[index]);
                      }
                    */

              );
            },
          );
        },
      ),

Пожалуйста, введите свой запрос и минимальный рабочий код, чтобы мы могли точно понять, в чем вопрос, и могли помочь

Huthaifa Muayyad 30.03.2021 06:14

@Huthaifa Muayyad, я чувствую ответ на свой неясный вопрос, и я делаю демо-приложение прямо сейчас! ~ @ _ @

Ryan Wang 30.03.2021 08:09

см. CombineLatestStream

pskink 30.03.2021 08:26

@pskink, спасибо за ответ, я только что проверил CombineLatest Stream, но он не работает, так как я хочу отсортировать их по времени после объединения этих двух потоков. :(

Ryan Wang 30.03.2021 08:57

да, это работает - документы говорят: «Объединяет заданные потоки в одну последовательность потоков с помощью функции combiner всякий раз, когда какая-либо из последовательностей исходного потока испускает элемент». - так что вы можете делать все, что хотите, в функции combiner

pskink 30.03.2021 09:12

Хорошо, я попробую это, и я дам вам знать, сработает он для меня или нет, еще раз очень благодарен вашему пациенту.

Ryan Wang 30.03.2021 09:35

@pskink, попробовал, работает! Еще раз спасибо, но на самом деле вы можете опубликовать его как «Ответ» вместо комментария, так что в этом случае я могу отметить ваш ответ как правильный! @ _ @

Ryan Wang 30.03.2021 22:43

добро пожаловать, "но на самом деле вы можете опубликовать это [...]" - тогда опубликуйте ответ самостоятельно ;-)

pskink 31.03.2021 07:41
Интеграция Angular - Firebase Analytics
Интеграция Angular - Firebase Analytics
Узнайте, как настроить Firebase Analytics и отслеживать поведение пользователей в вашем приложении Angular.
0
8
52
0

Другие вопросы по теме