Search code examples
flutterdartlistviewgoogle-cloud-firestore

RangeError (RangeError (index): Invalid value: Valid value range is empty: 0) flutter firebase firestore supposed to make a list view but throws error


Here we have the home screen and a firebaseFirestore database

so the database looks like this :

(collection) Users -> user1 -> (sub) groups -> title & members & Admin

at the error ( Text(groups[0][0]) ) it is supposed to make a listView that contains the groups. if i put anything instead of groups[0][0] for e.g 'work it works but instead it throws his error, Thanks

Home Screen code:

import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:gamerzland/Screens/SignInScreen.dart';
import 'package:gamerzland/groupTile.dart';
import 'package:hive/hive.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'ProfileScreen.dart';

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

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  final _box = Hive.box("account");
  String username ='';
  dynamic color = Colors.cyan.shade200;




  @override
  Widget build(BuildContext context)  {
    List groups = [];
    print('s ${groups}');
    var db = FirebaseFirestore.instance;
    String title = '';
    db.collection('users').doc(FirebaseAuth.instance.currentUser!.uid)
        .collection('groups').get().then((doc) {
      doc.docs.forEach((element) {

        groups.add([element['title'],element['members'],element['Admin']]);
        print(groups[0][0]);
      });
    });

    return Scaffold(
      body: ListView(
        children: [

          Text(groups[0][0])
          ]
          ),

      backgroundColor: Colors.deepPurple[100],
      appBar: AppBar(backgroundColor: Colors.deepPurple[300],title: SizedBox(child:Container( color: Colors.white,child: TextField(decoration: InputDecoration(prefixIcon: Icon(Icons.search),hintText: 'Search...'),))), centerTitle: true,),
      drawer: Drawer(
        backgroundColor: Colors.white,
        width: MediaQuery.of(context).size.width * 0.65,

        child: SingleChildScrollView(
            child: Column(
                children: [
                  SizedBox(height: 0.3 * MediaQuery.of(context).size.height,child: Container(
                    color: Colors.deepPurple[300],
                    child: Column(
                      children: [
                        SizedBox(height: MediaQuery.of(context).size.height * 0.015,),
                    CircleAvatar(
                      radius: 55.0,
                        backgroundColor:  getColor(_fetchAvatar()),
                       child: FutureBuilder(
                         future: _fetchUsername(),
                         builder: (context,snapshot){
                           if(snapshot.connectionState == ConnectionState.done){
                             return   Text(username[0],style: TextStyle(fontSize: 45.0 * MediaQuery.of(context).textScaleFactor),);
                           }
                           return   Text('',style: TextStyle(fontSize: 19.0 * MediaQuery.of(context).textScaleFactor),);
                         },
                       ),
                    ),
                        SizedBox(height: MediaQuery.of(context).size.height * .02,),

                        FutureBuilder(
                          future: _fetchUsername(),
                          builder: (context,snapshot){
                            if(snapshot.connectionState == ConnectionState.done){
                              return   Text(username,style: TextStyle(fontSize: 20.0 * MediaQuery.of(context).textScaleFactor),);
                            }
                            return   Text('Loading..',style: TextStyle(fontSize: 18.0 * MediaQuery.of(context).textScaleFactor),);
                          },
                        ),
                        Text('${FirebaseAuth.instance.currentUser!.email}',style: TextStyle(fontSize: 17.0 * MediaQuery.of(context).textScaleFactor),)

                      ],
                    ),

                    width: MediaQuery.of(context).size.width * 0.65,
                  ),),
                  SizedBox(height: MediaQuery.of(context).size.height * 0.05,),
                  Row( children : [

                    SizedBox(height: MediaQuery.of(context).size.height * 0.015,),

          Icon(Icons.account_circle_rounded),

          GestureDetector(

            child:
          Text(' Profile',style: TextStyle(fontSize: 30.0 * MediaQuery.of(context).textScaleFactor),), onTap: (){
            Navigator.push(context, MaterialPageRoute(builder: (context) => ProfileScreen()));
          },)
                                  ]
                  ),
                  SizedBox(height: MediaQuery.of(context).size.height * 0.015,),
                  Row( children : [
                    SizedBox(width: MediaQuery.of(context).size.width * 0.015,),
                    Icon(Icons.logout),
                    GestureDetector(onTap: (){
                      FirebaseAuth.instance.signOut().then((value) => {
                        _box.delete(1),
                        Navigator.push(context, MaterialPageRoute(builder: (context) => SignInScreen()))
                      });
                    },child: Text(' Logout',style: TextStyle(fontSize:30.0 * MediaQuery.of(context).textScaleFactor),))
                  ]
                  )
                ]
            )
        ),
      ),
    );
  }


  _fetchUsername() async{
    if(FirebaseAuth.instance.currentUser != null){
      await FirebaseFirestore.instance.collection("users").
      doc(FirebaseAuth.instance.currentUser!.uid)
          .get().
      then((value) =>
      {
        username = value['Username']
      }).onError((error, stackTrace) => {
      });
    }
  }

  _fetchAvatar() async{
    if(FirebaseAuth.instance.currentUser != null){
      await FirebaseFirestore.instance.collection("users").
      doc(FirebaseAuth.instance.currentUser!.uid)
          .get().
      then((value) =>
      {
        color = value['avatar']
      }).onError((error, stackTrace) => {

      });
    }
    if(color == 'cyan200'){
      return color;
    }

  }
  Color getColor(dynamic color) {
    if (color == 'cyan200') {
      return Colors.cyan.shade200;
    }

    else{
      return Colors.cyan.shade200;
    }
  }
  }

Solution

  • You are using .then to fetch data,

     .collection('groups').get().then((doc) {
    

    It will take some frame to fetch.

    You can do data check

    Text(
        "${groups.isNotEmpty && groups.first.isNotEmpty ? groups[0][0] : "Got null"}"),
    

    But I will suggest using FutureBuilder/StreamBuilder. Also dont define variable inside build method.