0

I am currently working on a screen in a project where the user can see a list of posts that he or she has subscribed, ordered by the time they were last updated (using a timestamp field in the post document). Currently this is done by retrieving an array of Post Document IDs from the user's profile document through a future builder, and then using that array for a wherein query in a streambuilder that works with a listview builder so they can do the lazy loading thing and also can update in real time. My problem is the wherein limit of 10 values in the array, and I'm not certain of the way I should go about working around it. This is my code:

import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:testApp/myServices/postDisplay.dart';

class homeView extends StatefulWidget {
  const homeView({Key? key}) : super(key: key);

  @override
  State<homeView> createState() => _homeViewState();
}

class _homeViewState extends State<homeView> {
  final FirebaseAuth auth = FirebaseAuth.instance;
  final db = FirebaseFirestore.instance;
  late String currentUID;
  bool isReady = false;
  List subscriptions = ['1, 2, 3'];
  Stream<QuerySnapshot<Object?>>? postStream;

  getProfileData() async {
    return await db.collection("Profiles").doc(currentUID).get().then((value) {
      subscriptions = value.data()!["subscriptions"];
      postStream = db
          .collection("Posts")
          .where(FieldPath.documentId, whereIn: subscriptions)
          .snapshots();
      isReady = true;
    });
  }

  void initState() {
    currentUID = auth.currentUser!.uid;
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: FutureBuilder(
          future: getProfileData(),
          builder: (context, snapshot) {
            if (isReady) {
              return StreamBuilder<QuerySnapshot>(
                stream: postStream,
                builder: ((context, snapshot) {
                  if (!snapshot.hasData) {
                    return Center(child: CircularProgressIndicator());
                  } else {
                    return Center(
                      child: Container(
                        width: 300,
                        child: ListView.builder(
                          itemCount: snapshot.data!.docs.length,
                          itemBuilder: (context, index) {
                            return postDisplay(
                              postSnapshot: snapshot.data!.docs[index],
                              currentUID: currentUID,
                            );
                          },
                        ),
                      ),
                    );
                  }
                }),
              );
            } else {
              return Center(
                child: CircularProgressIndicator(),
              );
            }
          }),
    );
  }
}

I have thought of splitting the array into chunks/batches and doing queries that way (as seen in some of the other similar questions on here), or even flipping the database scheme upside-down by storing the IDs of the users into the post documents and using the array contains query as it is not limited. I am somewhat inclined against this, however, as I want the post documents to contain as little information as possible as they're the most often loaded element in the project- the way that the project is set up means that certain popular individual posts would most likely have more people attached to it as subscribers than the average user would have posts attached to it as entities he or she follows. No matter what the solution, the resulting list needs to be ordered (this is what kind of differentiates my problem from the other questions on the site I think) by time of last modification (using the field in the post document). I'm not sure if this requirement makes chunks/batching unfeasible. Please let me know if you have any suggestions on how to succeed. Thank you so much in advance for any help!

Dharmaraj
  • 47,845
  • 8
  • 52
  • 84
Dingo99
  • 3
  • 2
  • You'll have to run multiple queries with 10 items at a time or either fetch each document separately. Check the linked documentation for more info, – Dharmaraj Feb 01 '23 at 09:22
  • ``` getProfileData() async { return await db.collection("Profiles").doc(currentUID).get().then((value) { subscriptions = value.data()!["subscriptions"]; postStream = db .collection("Posts") .where(FieldPath.documentId, whereIn: subscriptions) .orderBy("lastModified", descending: true) .snapshots(); isReady = true; }); } ``` – Chetan patil Feb 01 '23 at 09:26

0 Answers0