Home > Software engineering >  Flutter getAll operation from Firestore returning null
Flutter getAll operation from Firestore returning null

Time:04-26

I am trying to get all the documents related to a collection from Firestore, but it returns null. The below code is working for the users collection (retrieving only one user), but for masterclasses not.

This is my Firestore database:

enter image description here

And the code related to it:

    import 'dart:developer';

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:womanverse/model/masterclass.dart';
import 'package:womanverse/model/user.dart';

class DatabaseService {

  final String? uid;
  DatabaseService ({ this.uid });
  final CollectionReference userCollection = FirebaseFirestore.instance.collection('users');
  final CollectionReference masterclassesCollection = FirebaseFirestore.instance.collection('masterclasses');

  Future updateUserData(String email, String name, String phoneNumber, bool isSubscribed) async {
    return userCollection.doc(uid).set({
      'email' : email,
      'name' : name,
      'phoneNumber' : phoneNumber,
      'isSubscribed' : isSubscribed,
    });
  }

  Future updateName(String name) async {
    return userCollection.doc(uid).update({
      'name' : name,
    });
  }

  Future updateEmail(String email) async {
    return userCollection.doc(uid).update({
      'email' : email,
    });
  }

  Future updatePhoneNumber(String phoneNumber) async {
    return userCollection.doc(uid).update({
      'phoneNumber' : phoneNumber,
    });
  }

  Future updateSubscribe(bool subscribe) async {
    return userCollection.doc(uid).update({
      'isSubscribed' : subscribe,
    });
  }

  //user from Document
  MyUser userFromDocument (DocumentSnapshot snapshot){

    var sn = snapshot.data() as Map<String, dynamic>;

    return MyUser(
      uid: sn['uid'],
      name: sn['name'],
      email: sn['email'],
      phoneNumber: sn['phoneNumber'],
      isSubscribed: sn['isSubscribed']
    );
  }

  Stream<MyUser> get mySingleUser {
    return userCollection.doc(uid).snapshots().map(userFromDocument);
  }

  List<Masterclass> masterclassesConvert (QuerySnapshot snapshot)  {
    return snapshot.docs.map((doc){
      return Masterclass(
          uid: doc.get('uid') ?? "",
          authorImage: doc.get('authorImage') ?? "",
          authorName: doc.get('authorName') ?? "",
          classImage: doc.get('classImage') ?? "",
          className: doc.get('className') ?? ""
      );
    }).toList();

}

  Stream<List<Masterclass>> get masterclasses {
    return masterclassesCollection.snapshots().map(masterclassesConvert);
  }


}

I am using Stream Provider to listen any changes for masterclass collection:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:persistent_bottom_nav_bar/persistent-tab-view.dart';
import 'package:provider/provider.dart';
import 'package:sizer/sizer.dart';
import 'package:womanverse/db/firestore_database.dart';
import 'package:womanverse/model/masterclass.dart';
import 'package:womanverse/pages/home/masterclasses/learnmore.dart';
import 'package:womanverse/pages/home/masterclasses/session.dart';
import 'package:womanverse/pages/home/masterclasses/education_sessions_list.dart';


class Education extends StatelessWidget {
  const Education({Key? key}) : super(key: key);



  @override
  Widget build(BuildContext context) {
    //precacheImage(const AssetImage("assets/background-marmura.png"), context);

    return StreamProvider<List<Masterclass>>.value(
      value: DatabaseService().masterclasses,
      initialData: const [],
      child: Sizer(
          builder: (context, orientation, deviceType) {
            return Scaffold(
                body: SafeArea(
                  child: SingleChildScrollView(
                      child: Column(
                        children: [
                          SizedBox(height:7.h),
                          Container(
                            margin: const EdgeInsets.fromLTRB(20, 0, 20, 0),
                            child: Row(
                              mainAxisAlignment: MainAxisAlignment.center,
                              children:  [
                                Flexible(
                                    child: Text("ELITE MASTERCLASSES",
                                      textAlign: TextAlign.center,
                                      style: TextStyle(
                                        fontSize: SizerUtil.deviceType == DeviceType.mobile ? 20.sp : 17.sp,
                                        letterSpacing: 3,
                                        color: const Color(0xff393432),
                                        fontFamily: 'RoyaleBold',
                                      ),)
                                ),
                              ],
                            ),
                          ),
                          SizedBox(height:3.h),
                          ElevatedButton(
                            style: ButtonStyle(
                                padding: MaterialStateProperty.all(EdgeInsets.fromLTRB(3.w, 1.h, 3.w, 1.h)),
                                elevation: MaterialStateProperty.all(5), //Defines Elevation
                                backgroundColor: MaterialStateProperty.all(const Color(0xffE4BCB4)),
                                shape: MaterialStateProperty.all<RoundedRectangleBorder>(
                                    RoundedRectangleBorder(
                                      borderRadius: BorderRadius.circular(10.0),
                                    )
                                )
                            ),
                            onPressed: () {
                              pushNewScreen(context,
                                  screen: const LearnMore(),
                                  withNavBar: true,
                                  pageTransitionAnimation: PageTransitionAnimation.slideRight);
                            },
                            child: Text("LEARN MORE",
                                style: TextStyle(
                                  color: const Color(0xff393432),
                                  fontSize: SizerUtil.deviceType == DeviceType.mobile ? 10.sp : 9.sp,
                                  fontWeight: FontWeight.bold,
                                )
                            ),
                          ),
                          SizedBox(height: 2.h),
                          Container(
                            margin: const EdgeInsets.fromLTRB(10, 0, 0, 0),
                            child: SizedBox(
                              height: 35.h,
                              child: const SessionsList(),
                            ),
                          ),


                          SizedBox(height: 7.h),
                          Container(
                            width: 100.w,
                            color: Colors.black,
                            padding: const EdgeInsets.all(20),
                            child: Column(
                              children: [
                                Row(
                                  children: [
                                    Text("NFT",
                                      textAlign: TextAlign.center,
                                      style: TextStyle(
                                        fontSize: SizerUtil.deviceType == DeviceType.mobile ? 20.sp : 17.sp,
                                        letterSpacing: 3,
                                        color: Colors.white,
                                        fontFamily: 'RoyaleBold',
                                      ),),
                                  ],
                                ),
                                SizedBox(height: 2.h),
                                Row(
                                  children: [
                                    Stack(
                                      children:[
                                        SizedBox(
                                          width: 100.w - 40,
                                          height: 30.h,
                                          child: Card(
                                            semanticContainer: true,
                                            clipBehavior: Clip.antiAliasWithSaveLayer,
                                            child: Image.asset(
                                              'assets/background-marmura.png',
                                              fit: BoxFit.fill,
                                            ),
                                            shape: RoundedRectangleBorder(
                                              borderRadius: BorderRadius.circular(10.0),
                                            ),
                                            elevation: 5,
                                            margin: const EdgeInsets.all(10),
                                          ),
                                        ),
                                        Positioned(
                                          bottom: 20,
                                          right: 25,
                                          child: OutlinedButton(
                                            onPressed: () {

                                            },
                                            style: OutlinedButton.styleFrom(
                                              padding: const EdgeInsets.fromLTRB(17, 13, 17, 13),
                                              primary: const Color(0xffE4BCB4),
                                              shape: RoundedRectangleBorder(
                                                borderRadius: BorderRadius.circular(
                                                    10.0),
                                              ),
                                              side: const BorderSide(
                                                  width: 2, color: Color(0xff393432)),
                                            ),
                                            child: Text(
                                                'GO TO SESSION',
                                                style: TextStyle(
                                                  color: const Color(0xff393432),
                                                  fontSize: SizerUtil.deviceType == DeviceType.mobile ? 10.sp : 8.sp,
                                                  fontWeight: FontWeight.w700,
                                                )
                                            ),
                                          ),
                                        ),
                                      ],
                                    ),
                                  ],
                                )
                              ],
                            ),
                          ),
                        ],
                      )
                  ),
                )
            );
          }
      ),
    );
  }
}

Where I listen to:

import 'dart:developer';

import 'package:flutter/material.dart';
import 'package:persistent_bottom_nav_bar/persistent-tab-view.dart';
import 'package:provider/provider.dart';
import 'package:sizer/sizer.dart';
import 'package:womanverse/model/masterclass.dart';
import 'package:womanverse/pages/home/masterclasses/session.dart';

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

  @override
  State<SessionsList> createState() => _SessionsListState();
}


class _SessionsListState extends State<SessionsList> {

  createSessionThumbnail(String image, Widget newPage, context) {
    print("asda");
    return Stack(
      children:[
        SizedBox(
          width: 75.w,
          height: 35.h,
          child: Card(
            semanticContainer: true,
            clipBehavior: Clip.antiAliasWithSaveLayer,
            child: Image.network(
              image,
              fit: BoxFit.fill,
            ),
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(10.0),
            ),
            elevation: 5,
            margin: const EdgeInsets.all(10),
          ),
        ),
        Positioned(
          bottom: 20,
          right: 30,
          child: OutlinedButton(
            onPressed: () {
              pushNewScreen(context,
                  screen: newPage,
                  withNavBar: true,
                  pageTransitionAnimation: PageTransitionAnimation.slideRight);
            },
            style: OutlinedButton.styleFrom(
              padding: const EdgeInsets.fromLTRB(17, 13, 17, 13),
              primary: const Color(0xffE4BCB4),
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(
                    10.0),
              ),
              side: const BorderSide(
                  width: 2, color: Color(0xff393432)),
            ),
            child: Text(
                'GO TO SESSION',
                style: TextStyle(
                  color: const Color(0xff393432),
                  fontSize: SizerUtil.deviceType == DeviceType.mobile ? 10.sp : 8.sp,
                  fontWeight: FontWeight.w700,
                )
            ),
          ),
        ),
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    log("aaaa");
    final masterclasses = Provider.of<List<Masterclass>>(context);
    log("a");
    return ListView.builder(
      scrollDirection: Axis.horizontal,
      itemCount: masterclasses.length,
      itemBuilder: (BuildContext ctx, int index) {
        print("aa");
        return createSessionThumbnail(masterclasses[index].classImage!, const Session(), ctx);
      },

    );
  }
}

CodePudding user response:

I solved this issue by changing

  List<Masterclass> masterclassesConvert (QuerySnapshot snapshot)  {
    return snapshot.docs.map((doc){
      return Masterclass(
          uid: doc.data().toString().contains('uid') ? doc.get('uid') : '',
          authorImage: doc.data().toString().contains('authorImage') ? doc.get('authorImage') : '',
          authorName: doc.data().toString().contains('authorName') ? doc.get('authorName') : '',
          classImage: doc.data().toString().contains('classImage') ? doc.get('classImage') : '',
          className: doc.data().toString().contains('className') ? doc.get('className') : '',
      );
    }).toList();
  }

Somehow, the latest version of Firestore, should have this check: doc.data().toString().contains('authorImage')

  • Related