How to get data from two collections in firebase using Flutter

1,689

You can can make you body take a widget ListView and for the Listview children have both your lists.

example

body: ListView(
          children: <Widget>[
           ---list1----

            --list2-----   
          ]);

or you can use a custom scroll view

return new Scaffold(
    appBar: new AppBar(
        title: new Text("Project Details"),
        backgroundColor: Colors.blue[800]),
    body:
    new CustomScrollView(
        slivers: <Widget>[
          new SliverPadding(padding: const EdgeInsets.only(left: 10.0,right: 10.0,
              top: 10.0,bottom: 0.0),
            sliver: new SliverList(delegate:
            new SliverChildListDelegate(getTopWidgets())),
          ),
          new SliverPadding(padding: const EdgeInsets.all(10.0),
              sliver: new SliverList(delegate: new SliverChildListDelegate(
                  getSfListTiles()
              ))),
          new SliverPadding(padding: const EdgeInsets.all(10.0),
              sliver: new SliverList(delegate: new SliverChildListDelegate(
                  getWorkStatementTiles()
              ))),
        ]
    )

);

update from @Rémi Rousselet answer You can nest StreamBuilder

    StreamBuilder(
  stream: stream1,
  builder: (context, snapshot1) {
    return StreamBuilder(
      stream: stream2,
      builder: (context, snapshot2) {
        // do some stuff with both streams here
      },
    );
  },
)
Share:
1,689
Alfonso Angulo
Author by

Alfonso Angulo

Updated on December 20, 2022

Comments

  • Alfonso Angulo
    Alfonso Angulo over 1 year

    This is my problem:

    I have a ListPost StatefulWidget where I want to display a list of widgets that contains the user's account image, the user's name, and the user's posts images(similar to Facebook feeds), however, I have gotten to the point that I need to get that data from two different collections in Firebase (see my firebase collections image below).

    The good thing is that I have been able to get that data only from one collection(userFeed) and display that data in my ListPost file in different widgets, however, I do not know how to get data from another collection in Firebase using the same streamBuilder and display all that data I want to display in other widgets in my ListPost screen.

    So, my specific question is: How can I make my ListPost screen to populate data from 2 different collections in Firebase using a stream builder or another type of implementation?

    This is the firebase image

    enter image description here

    This is the complete code for the ListPost screen

    import 'package:cached_network_image/cached_network_image.dart';
    import 'package:cloud_firestore/cloud_firestore.dart';
    import 'package:flutter/material.dart';
    import 'models/post_model.dart';
    
    final _stream = Firestore.instance.collection('userFeed').snapshots();
    
    class ListPosts extends StatefulWidget {
    
      @override
      _ListPostsState createState() => _ListPostsState();
    }
    
    class _ListPostsState extends State<ListPosts> {
    
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Container(
            //this is the Streambuilder to get the data however it only lets me to get one collection
            child: StreamBuilder(
              stream: _stream,
              builder: (context, snapshot) {
                if (!snapshot.hasData) return const Text('Loading...');
                return ListView.builder(
                  itemExtent: 550.0,
                  itemCount: snapshot.data.documents.length,
                  itemBuilder: (BuildContext context, int data) {
                    //here I get the data from the userFeed colecction
                    Post post = Post.fromDoc(snapshot.data.documents[data]);
                    return Column(
                      children: <Widget>[
                        GestureDetector(
                          child: Container(
                            padding: EdgeInsets.symmetric(
                              horizontal: 16.0,
                              vertical: 10.0,
                            ),
                            child: Row(
                              children: <Widget>[
                                CircleAvatar(
                                  radius: 25.0,
                                  backgroundColor: Colors.grey,
                                  backgroundImage: post.imageUrl.isEmpty
                                      ? AssetImage(
                                          'assets/images/user_placeholder.jpg')
                                      : CachedNetworkImageProvider(post.imageUrl),
                                ),
                                SizedBox(width: 8.0),
                                Text(
                                  post.caption,
                                  style: TextStyle(
                                    fontSize: 18.0,
                                    fontWeight: FontWeight.w600,
                                  ),
                                ),
                              ],
                            ),
                          ),
                        ),
                        GestureDetector(
                          child: Stack(
                            alignment: Alignment.center,
                            children: <Widget>[
                              Container(
                                height: MediaQuery.of(context).size.width,
                                decoration: BoxDecoration(
                                  image: DecorationImage(
                                    image:
                                        CachedNetworkImageProvider(post.imageUrl),
                                    fit: BoxFit.cover,
                                  ),
                                ),
                              ),
                            ],
                          ),
                        ),
                      ],
                    );
                  },
                );
              },
            ),
          ),
        );
      }
    }
    

    UPDATE 05-22-2020 HOW I FIXED THE ISSUE Credits to the user griffins, he helped me to fix this issue.

    This is what I do:

    I nested my StreamBuilder so I can use 2 streams at the same time

     return StreamBuilder(
          stream: _stream,
          builder: (context, snapshot1) {
            return StreamBuilder(
              stream: _stream2,
              builder: (context, snapshot2) {
                if (!snapshot2.hasData) return const Text('Loading...');
                if (!snapshot1.hasData) return const Text('Loading...');
                return ListView.builder(
                  itemExtent: 550.0,
                  itemCount: snapshot2.data.documents.length,
                  itemBuilder: (BuildContext context, int data) {
                    User user = User.fromDoc(snapshot2.data.documents[data]);
                    Post post = Post.fromDoc(snapshot1.data.documents[data]);
                    return buildbody(user, post, context);
                  },
                );
              },
            );
          },
        );
    
  • Alfonso Angulo
    Alfonso Angulo almost 4 years
    None of the options worked, the first one give me an error and the second one does not let me to add the widget, but thanks
  • Alfonso Angulo
    Alfonso Angulo almost 4 years
    Bro, thanks a lot, I was able to fix the issue. thanks!
  • griffins
    griffins almost 4 years
    awesome, would be great if you marked this as answer for future visitors.