Bagaimana tepatnya menggabungkan beberapa aliran di firebase firestore

Sebelum Anda mengatakan ini adalah pertanyaan duplikat atau bahwa saya harus menggunakan pembuat aliran bersarang, harap dengarkan saya.

Saya sedang merancang aplikasi jenis media sosial. Dan saya ingin pengguna menerima pembaruan setiap kali seseorang yang mereka ikuti memposting sesuatu di koleksi Postingan Pengikut saya. Di dalam aplikasi, aplikasi akan memeriksa firebase rtdb untuk daftar berikut pengguna saat ini (orang-orang yang dia ikuti) dan membuat daftar ID mereka.

Saya berencana menggunakan daftar tersebut untuk membuat daftar aliran (tentu saja diurutkan berdasarkan waktu) dan menggabungkannya menjadi satu aliran yang kemudian akan dimasukkan ke pembuat aliran di halaman umpan pribadi.

Di halaman ini, pengguna akan dapat dengan mudah mengikuti apa yang telah diposting oleh orang-orang yang mereka minati.

Saya pikir sistem seperti itu jauh lebih hemat biaya daripada setiap pengguna yang memiliki dokumen di koleksi Umpan pribadi dan setiap kali seseorang memposting sesuatu, aplikasi membaca daftar pengikut mereka dan kemudian segera memposting pembaruan di setiap feed pribadi mereka. . Karena... Bayangkan seseorang dengan 2 juta pengikut. Itu berarti 2 juta penulisan secara instan. Dan kemudian, 2 juta membaca. Menurut saya, akan jauh lebih hemat biaya jika pembuat poster hanya memasang postingan di Umpan publik mereka dan pengikut yang berbeda cukup mendengarkan umpan tersebut dan terus memantau mereka.

Tapi.. Hal ini memerlukan penerapan penggabungan beberapa aliran (lebih dari 2). Bagaimana saya melakukan ini?

Saya telah mencoba membaca RxDart tetapi bagi saya itu sepenuhnya bahasa Yunani. Saya relatif seorang pemula dalam permainan dart. Saya baru coding sekitar 5 bulan sekarang.


person Simeon    schedule 20.08.2020    source sumber


Jawaban (2)


Anda dapat menggunakan StreamGroup dari paket async: https://pub.dev/documentation/async/latest/async/StreamGroup-class.html untuk mengelompokkan acara dari beberapa aliran - ini didokumentasikan dan dikelola dengan baik oleh tim dart. Jika Anda tidak memiliki pengalaman RxDart, ini adalah pilihan yang baik. Ia tidak memiliki semua fitur rx tetapi bagi pemula akan lebih mudah untuk memahaminya

person mgapinski    schedule 20.08.2020
comment
Bisakah Anda memberi saya contoh sederhana tentang cara melakukan ini. Saya belajar sepenuhnya melalui tutorial youtube, jadi, saya belum begitu pandai memecahkan kode cara penulisan dokumentasi. Saya belajar lebih baik dari contoh. Asumsikan Anda memiliki data di koleksi Mobil baru dan beberapa data lain di koleksi Pakaianbaru dan beberapa data lain di koleksi PapanKeyBoards baru. Bisakah Anda menulis beberapa kode demo tentang bagaimana Anda akan menggunakan async untuk menggabungkan ketiganya dan memasukkannya ke dalam pembuat aliran? - person Simeon; 22.08.2020
comment
Saya telah berhasil menggabungkan aliran menggunakan ini dan itu benar-benar berfungsi. Namun, saya menghadapi masalah baru dan sama sekali berbeda terkait menampilkan aliran gabungan di pembuat aliran. Saya akan mempostingnya sebagai pertanyaan baru. Terima kasih. - person Simeon; 24.08.2020

Saya baru-baru ini mengalami kasus serupa, dan yang saya sarankan Anda lakukan adalah ini (Saya menggunakan cloud firestore, tapi saya yakin streaming Anda sudah ditulis jadi yang penting adalah penggunaan beberapa aliran):

Anda harus menambahkan plugin ini ke pub spec.yaml: https://pub.dev/packages/rxdart

Berikut adalah repositori untuk (dalam kasus Anda posting, katakanlah newPosts, oldPosts):

class PostRepository {

  static CollectionReference get collection => yourCollectionRef;
    
  static Stream<List<Post>> newPosts() {
    Query query = collection
        .where('Your condition like was viewed', isEqualTo: false)
        .orderBy('updateDate', descending: true)
        .limit(50);
    return query.snapshots().map<List<Post>>((querySnapshot) {
      final _newPosts = querySnapshot.documents.map((doc) {
        final post = Post.fromDoc(doc);
        return post;
      }).where((p) => p != null);

      return _newPosts
    });
  }

  static Stream<List<Post>> oldPosts() {
    Query query = collection
        .where('Your condition like was viewed', isEqualTo: true)
        .orderBy('updateDate', descending: true)
        .limit(50);
    return query.snapshots().map<List<Post>>((querySnapshot) {
      final _oldPosts = querySnapshot.documents.map((doc) {
        final post = Post.fromDoc(doc);
        return post;
      }).where((p) => p != null);

      return _oldPosts
    });
  }
}

Kemudian untuk mendapatkan beberapa aliran (gabungan keduanya dari atas), lakukan seperti ini di kelas widget Anda:

PENTING! Anda harus mengimpor ini - import 'package:rxdart/streams.dart';

List<Post> newPosts;
List<Post> oldPosts;

Widget _pageContent() {
  return SingleChildScrollView(
    child: Column(
      children: [
        ListView.builder(
          shrinkWrap: true,
          physics: NeverScrollableScrollPhysics(),
          itemCount: newPosts.length,
          itemBuilder: (context, index) {
            return ListTile(
              title: Text(newPosts[index].title)
            );
          }
        ),
        ListView.builder(
          shrinkWrap: true,
          physics: NeverScrollableScrollPhysics(),
          itemCount: oldPosts.length,
          itemBuilder: (context, index) {
            return ListTile(
              title: Text(oldPosts[index].title)
            );
          }
        )
      ]
    )
  );
}

Widget _posts() {
  return StreamBuilder(
    stream: CombineLatestStream.list([
      PostRepository.getNewPosts(),
      PostRepository.getOldPosts()
    ]),
    builder: (context, snap) {
     if (snap.hasError) {

        debugPrint('${snap.error}');
        return ErrorContent(snap.error);

      } else if (!snap.hasData) {

        return Center(
          child: CircularProgressIndicator(),
        );

      }

      newPosts = snap.data[0];
      oldPosts = snap.data[1];

      return _pageContent();
    }
  );
}

Saya menulis kode seperti dari kepala, jadi mungkin ada beberapa kesalahan kecil, tapi saya harap Anda mengerti maksudnya, selamat menikmati :)

person Nonstapp    schedule 20.08.2020
comment
Terima kasih banyak. Meskipun menurut saya tidak mungkin untuk menempatkan tampilan daftar di dalam tampilan gulir. Saya telah melakukan itu sebelumnya dan itu memberikan beberapa kesalahan seperti Anda tidak dapat meletakkan benda yang dapat digulir di dalam benda yang dapat digulir lainnya, bodoh. Saya akan mencoba solusi Anda dan saya akan memberi Anda masukan. - person Simeon; 22.08.2020
comment
Oke. Jika Anda menggunakan shrinkwrap dan neverscrollablescrollphysics seperti pada contoh, 2 daftar Anda akan berfungsi sempurna seperti yang Anda inginkan :) - person Nonstapp; 22.08.2020
comment
Terima kasih banyak. Saya berhasil menggabungkan aliran menggunakan grup aliran, tetapi saat ini saya menghadapi masalah baru dengan menampilkan aliran gabungan ini di pembuat aliran. Tapi saya mempostingnya sebagai pertanyaan yang sama sekali baru. Terima kasih. - person Simeon; 24.08.2020
comment
Perhatikan bahwa jika Anda ingin menggabungkan aliran koleksi (Stream‹List‹T›› dan bukan Stream‹T›, Anda perlu menggunakan fungsi penggabung khusus - dalam contoh ini dia memanggil CombineLatestStream.list yang menggunakan penggabung default yang bagus untuk Stream‹T›. Dalam kasus saya, saya tidak dapat membuatnya berfungsi sampai saya menyadari ketika menggunakan Stream‹List‹T›› Anda perlu menyediakan penggabung khusus untuk menanganinya (dapatkan List‹List‹T›› lalu ratakan itu untuk mendapatkan Stream‹List‹T›› sesuai kebutuhan). Jadi, Anda perlu menggunakan CombineLatestStream(streamList, combinerFunc) biasa. - person Guy; 13.02.2021