วิธีรวมหลายสตรีมใน firebase firestore

ก่อนที่คุณจะบอกว่านี่เป็นคำถามซ้ำหรือว่าฉันควรใช้ตัวสร้างสตรีมแบบซ้อน โปรดฟังฉันก่อน

ฉันกำลังออกแบบแอปพลิเคชันประเภทโซเชียลมีเดีย และฉันต้องการให้ผู้ใช้ได้รับการอัปเดตทุกครั้งที่มีคนติดตามโพสต์บางอย่างในคอลเลกชันโพสต์ผู้ติดตามของฉัน ในแอป แอปจะตรวจสอบ firebase rtdb สำหรับรายการต่อไปนี้ของผู้ใช้ปัจจุบัน (คนที่เขาติดตาม) และสร้างรายการ uids ของพวกเขา

ฉันวางแผนที่จะใช้รายการดังกล่าวเพื่อสร้างรายการสตรีม (เรียงลำดับตามเวลา) และรวมเข้าด้วยกันเป็นสตรีมเดียว จากนั้นจะถูกป้อนเข้าสู่ตัวสร้างสตรีมบนหน้าฟีดส่วนตัว

ในหน้านี้ ผู้ใช้จะสามารถติดตามสิ่งที่ผู้สนใจโพสต์ได้อย่างง่ายดาย

ฉันคิดว่าระบบดังกล่าวคุ้มค่ากว่าผู้ใช้ทุกคนที่มีเอกสารในคอลเลกชันฟีดส่วนตัว และเมื่อใดก็ตามที่มีคนโพสต์บางสิ่ง แอปจะอ่านรายชื่อผู้ติดตามของพวกเขา จากนั้นจึงโพสต์การอัปเดตในฟีดส่วนตัวแต่ละรายการทันที . เพราะ... ลองนึกภาพคนที่มีผู้ติดตามถึง 2 ล้านคนสิ นั่นคือ 2 ล้านการเขียนทันที และต่อมาก็มีการอ่านถึง 2 ล้านครั้ง ฉันคิดว่าการที่ผู้โพสต์โพสต์โพสต์ในฟีดสาธารณะจะคุ้มค่ากว่ามาก และผู้ติดตามคนอื่นๆ ก็ฟังฟีดนั้นและติดตามแท็บต่างๆ ของพวกเขา

แต่ .. สิ่งนี้จำเป็นต้องมีการรวมหลายสตรีม (มากกว่า 2) ฉันจะทำอย่างไร?

ฉันได้ลองอ่านใน RxDart แล้ว แต่มันเป็นภาษากรีกทั้งหมดสำหรับฉัน ฉันค่อนข้างเป็นผู้เริ่มต้นโผ ตอนนี้ฉันเพิ่งเขียนโค้ดได้ประมาณ 5 เดือนเท่านั้น


person Simeon    schedule 20.08.2020    source แหล่งที่มา


คำตอบ (2)


คุณสามารถใช้ StreamGroup จากแพ็คเกจ async: https://pub.dev/documentation/async/latest/async/StreamGroup-class.html เพื่อจัดกลุ่มกิจกรรมจากหลายสตรีม - ได้รับการจัดทำเป็นเอกสารและดูแลรักษาอย่างดีโดยทีมงานโผ หากคุณไม่มีประสบการณ์ RxDart นี่เป็นตัวเลือกที่ดี มันไม่ได้มีคุณสมบัติทั้งหมดของ rx แต่สำหรับมือใหม่ ควรจะง่ายกว่านี้

person mgapinski    schedule 20.08.2020
comment
คุณช่วยยกตัวอย่างง่ายๆ เกี่ยวกับวิธีการทำเช่นนี้ให้ฉันหน่อยได้ไหม ฉันกำลังเรียนรู้อย่างสมบูรณ์จากบทช่วยสอนของ YouTube ดังนั้นฉันจึงยังถอดรหัสวิธีการเขียนเอกสารไม่เก่งนัก ฉันเรียนรู้ได้ดีขึ้นจากตัวอย่าง สมมติว่าคุณมีข้อมูลในคอลเลกชัน Cars ใหม่ และข้อมูลอื่นๆ บางส่วนที่ newClothesCollection และข้อมูลอื่นๆ บางส่วนที่คอลเลกชัน newKeyBoards คุณช่วยกรุณาเขียนโค้ดสาธิตเกี่ยวกับวิธีการใช้ async เพื่อรวมทั้งสามสิ่งนี้และป้อนลงในเครื่องมือสร้างสตรีมได้ไหม - person Simeon; 22.08.2020
comment
ฉันจัดการรวมสตรีมโดยใช้สิ่งนี้และใช้งานได้จริง อย่างไรก็ตาม ฉันกำลังเผชิญกับปัญหาใหม่ที่แตกต่างไปจากเดิมอย่างสิ้นเชิงเกี่ยวกับการแสดงสตรีมที่ผสานในตัวสร้างสตรีม ฉันจะโพสต์มันเป็นคำถามใหม่ ขอบคุณ - person Simeon; 24.08.2020

ฉันเพิ่งมีกรณีที่คล้ายกัน และสิ่งที่ฉันแนะนำให้คุณทำคือ (ฉันใช้ cloud firestore แต่ฉันแน่ใจว่าคุณได้เขียนสตรีมของคุณไว้แล้ว ดังนั้นส่วนสำคัญคือการใช้หลายสตรีม):

คุณต้องเพิ่มปลั๊กอินนี้ใน pub spec.yaml: https://pub.dev/packages/rxdart

นี่คือพื้นที่เก็บข้อมูลสำหรับ (ในโพสต์เคสของคุณ สมมติว่า 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
    });
  }
}

จากนั้นหากต้องการรับหลายสตรีม (ทั้งสองจากด้านบนรวมกัน) ให้ทำสิ่งนี้ในคลาสวิดเจ็ตของคุณ:

สำคัญ! คุณต้องนำเข้าสิ่งนี้ - นำเข้า '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();
    }
  );
}

ฉันเขียนโค้ดเหมือนจากส่วนหัว ดังนั้นอาจมีข้อผิดพลาดเล็กน้อย แต่ฉันหวังว่าคุณจะเข้าใจประเด็น ขอให้สนุกนะ :)

person Nonstapp    schedule 20.08.2020
comment
ขอบคุณมาก. แม้ว่าฉันไม่คิดว่าเป็นไปได้ที่จะใส่มุมมองรายการไว้ในมุมมองแบบเลื่อน ฉันเคยทำแบบนั้นมาก่อนแล้ว และมันทำให้เกิดข้อผิดพลาดในบรรทัดว่าคุณไม่สามารถใส่สิ่งที่เลื่อนได้เข้าไปข้างในหุ่นจำลองที่เลื่อนได้อื่น ฉันจะลองใช้วิธีแก้ปัญหาของคุณ และฉันจะให้ข้อเสนอแนะแก่คุณ - person Simeon; 22.08.2020
comment
ตกลง. หากคุณใช้ Shrinkwrap และ Neverscrollablescrollphysics ดังตัวอย่าง 2 รายการของคุณควรทำงานได้อย่างสมบูรณ์แบบตามที่คุณต้องการ :) - person Nonstapp; 22.08.2020
comment
ขอบคุณมาก. ฉันจัดการเพื่อรวมสตรีมโดยใช้กลุ่มสตรีม แต่ขณะนี้ฉันกำลังเผชิญกับปัญหาใหม่ในการแสดงสตรีมที่รวมแล้วในตัวสร้างสตรีม แต่ฉันโพสต์มันเป็นคำถามใหม่ทั้งหมด ขอบคุณนะ. - person Simeon; 24.08.2020
comment
โปรดสังเกตว่าหากคุณต้องการรวมสตรีมคอลเลกชัน (Stream‹List‹T›› และไม่ใช่ Stream‹T› คุณต้องใช้ฟังก์ชันตัวรวมแบบกำหนดเอง - ในตัวอย่างนี้เขาเรียก CombineLatestStream.list ซึ่งใช้ตัวรวมเริ่มต้นซึ่งดี สำหรับ Stream‹T› ในกรณีของฉันฉันไม่สามารถทำให้มันทำงานได้จนกว่าฉันจะรู้ว่าเมื่อใช้ Stream‹List‹T›› คุณต้องจัดเตรียมตัวรวมแบบกำหนดเองเพื่อจัดการมัน (รับ List‹List‹T›› จากนั้นจึงแบน เพื่อรับ Stream‹List‹T›› ตามต้องการ) ดังนั้นคุณต้องใช้ CombineLatestStream(streamList, combinerFunc) ปกติ - person Guy; 13.02.2021