0

i want to make a grid of image by 3 like instagram based on user upload. the streambuilder is not displaying any data from firestore. i already separate the stream so its not inside the streambuilder.

this is the code

import 'dart:io';

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:image_cropper/image_cropper.dart';
import 'package:image_picker/image_picker.dart';

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {

  File? imageFile;
  String? imageUrl;
  final FirebaseAuth _auth = FirebaseAuth.instance;

  String? myImage;
  String? myName;

  String buttonName = 'click';
  int currentIndex = 0;
  final icon = CupertinoIcons.chat_bubble_2;

  final _constructed = FirebaseFirestore.instance
      .collection('fotoupload')
      .orderBy("createAt", descending: true)
      .snapshots(); //construct stream first

//final Stream<QuerySnapshot> _constructed = FirebaseFirestore.instance
//      .collection('fotoupload')
//      .orderBy("createAt", descending: true)
//      .snapshots();

  void read_userInfo() async {
    FirebaseAuth.instance.currentUser!;
    FirebaseFirestore.instance
        .collection('users')
        .doc(FirebaseAuth.instance.currentUser!.uid)
        .get()
        .then<dynamic>((DocumentSnapshot snapshot) async {
      myImage = snapshot.get('userImage');
      myName = snapshot.get('name');
    });
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    read_userInfo(); // refresh and read the user info both myName and myImage
  }

Widget gridViewWidget(String docId, String img, String userImg, String name,
      DateTime date, String userId, int downloads) {
    return GridView.count(
      primary: false,
      padding: EdgeInsets.all(5),
      crossAxisSpacing: 1,
      crossAxisCount: 1,
      children: [
        GestureDetector(
          onTap: () {
            //createOwnerDetails
          },
          child: Center(
            child: Text(date.toString()),
          ),
        ),
        GestureDetector(
          onTap: () {
            //createOwnerDetails
          },
          child: Image.network(
            img,
            fit: BoxFit.cover,
          ),
        ),
        Center(child: Text(userId)),
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: StreamBuilder<QuerySnapshot>(
        stream: _constructed,
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return Center(
              child: CircularProgressIndicator(),
            );
          } else if (snapshot.connectionState == ConnectionState.active) {
            if (snapshot.data!.docs.isNotEmpty) {
              return GridView.builder(
                itemCount: snapshot.data!.docs.length,
                gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                    crossAxisCount: 3),
                itemBuilder: (BuildContext context, int index) {
                  return gridViewWidget(
                    snapshot.data!.docs[index].id,
                    snapshot.data!.docs[index]['Image'],
                    snapshot.data!.docs[index]['userImage'],
                    snapshot.data!.docs[index]['name'],
                    snapshot.data!.docs[index]['createAt '].toDate(),
                    snapshot.data!.docs[index]['uid'],
                    snapshot.data!.docs[index]['downloads'],
                  );
                },
              );
            } else {
              return Center(
                child: Text(
                  'There is no tasks',
                  style: TextStyle(fontSize: 20),
                ),
              );
            }
          }
          return Center(
            child: Text(
              'Something went wrong',
              style: TextStyle(fontWeight: FontWeight.bold, fontSize: 30),
            ),
          );
        },
      ),
    );
  }
}

does anyone have suggestion? the streambuilder is not displaying the data. and its shows "There is no task".

enter image description here

Debug Console

2
  • You are reconstructing the stream again after every build, I recommend you to construct the stream in a private variable then use it in the stream in place of FirebaseFirestore.instance.collection('fotoupload').orderBy("createAt", descending: true).snapshots() Commented Nov 26, 2022 at 11:55
  • thankyou sir for looking into this.. i do as you told me to and updated the code, but it still cannot display the data :) Commented Nov 26, 2022 at 13:03

2 Answers 2

1

You are reconstructing the stream again after every build, I recommend you to construct the stream in a private variable then use it in the stream in place of FirebaseFirestore.instance.collection('fotoupload').orderBy("createAt", descending: true).snapshots()

as documented here It is implemented like this

class _HomePageState extends State<HomePage> {
final _constrcted = FirebaseFirestore.instance
        .collection('fotoupload')
        .orderBy("createAt", descending: true)
        .snapshots();
//....
  @override
  Widget build(BuildContext context) {
    return Scaffold(body: StreamBuilder<QuerySnapshot>(
        stream: _constrcted,
        builder: (context, snapshot) {
       //...
}

Sign up to request clarification or add additional context in comments.

Comments

1
    stream: FirebaseFirestore.instance
        .collection('fotoupload')
        .orderBy("createAt", descending: true)
        .snapshots(),

There's your prooblem. Do not create the stream in the stream: parameter of a StreamBuilder. It will get re-created on each call to build(), up to 60 times per second if there's an animation on the page. This doesn't give time for any data to appear... in fact it throws it away on each rebuild.

Follow the advice from the FutureBuilder and StreamBuilder documentation: create and initialize the stream in the state and initState of your widget. The value must remain constant for StreamBuilder to do its job.

I have more details and a demonstration at https://youtu.be/sqE-J8YJnpg.

3 Comments

i update the code a bit, i add circularprogress indicator based on connectionstate and add AsyncSnapshot in the builder. Sir can you kindly show me how to it the right way? im sorry im new to flutter and still learning.
the name and userImage is not null anymore now
Sir thankyou, i already do it as suggested by @Rohit Kharche and updated the code

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.