skip to Main Content

I have two collections::

  1. group
  2. group users

The group users collection has documents …
Each document has two fields

  1. Group id
  2. User id

Group users collection

The group collection has documents …
Each document has two fields

  1. Group manager id
  2. Group name

group collection

Using the currently logged-in user, I want to do the following:

  • query the group users collection to get the groups id,

  • query the groups collection to get the groups name.

Pretty simple I think… BUT I CANT DO IT

This is the function that I am using:

  printData() {
    var arr = [];
    groupUser.snapshots().listen((data) {
      data.docs.forEach((element) {
        print(element['Group id']);
        arr.add(element['Group id']);
      });
    });
    return arr.first;
  }

I get the error below, but the print statement works:

The following StateError was thrown building TestView(dirty, state: _TestViewState#38814):
Bad state: No element

The relevant error-causing widget was
TestView
lib/views_and_widgets/navigator_view.dart:36
When the exception was thrown, this was the stack
#0      List.first (dart:core-patch/growable_array.dart:343:5)
#1      FirebaseCloudStorage.printData
package:ijob_clone_app/…/cloud/firebase_cloud_storage.dart:87
#2      _TestViewState.build
package:ijob_clone_app/views_and_widgets/test_view.dart:35
#3      StatefulElement.build
package:flutter/…/widgets/framework.dart:4992
#4      ComponentElement.performRebuild
package:flutter/…/widgets/framework.dart:4878
#5      StatefulElement.performRebuild
package:flutter/…/widgets/framework.dart:5050
#6      Element.rebuild
package:flutter/…/widgets/framework.dart:4604
#7      ComponentElement._firstBuild
package:flutter/…/widgets/framework.dart:4859
#8      StatefulElement._firstBuild
package:flutter/…/widgets/framework.dart:5041
#9      ComponentElement.mount
package:flutter/…/widgets/framework.dart:4853
...     Normal element mounting (25 frames)
#34     Element.inflateWidget
package:flutter/…/widgets/framework.dart:3863
#35     MultiChildRenderObjectElement.inflateWidget
package:flutter/…/widgets/framework.dart:6435
#36     MultiChildRenderObjectElement.mount
package:flutter/…/widgets/framework.dart:6447
...     Normal element mounting (113 frames)
#149    Element.inflateWidget
package:flutter/…/widgets/framework.dart:3863
#150    Element.updateChild
package:flutter/…/widgets/framework.dart:3586
#151    ComponentElement.performRebuild
package:flutter/…/widgets/framework.dart:4904
#152    StatefulElement.performRebuild
package:flutter/…/widgets/framework.dart:5050
#153    Element.rebuild
package:flutter/…/widgets/framework.dart:4604
#154    BuildOwner.buildScope
package:flutter/…/widgets/framework.dart:2667
#155    WidgetsBinding.drawFrame
package:flutter/…/widgets/binding.dart:882
#156    RendererBinding._handlePersistentFrameCallback
package:flutter/…/rendering/binding.dart:378
#157    SchedulerBinding._invokeFrameCallback
package:flutter/…/scheduler/binding.dart:1175
#158    SchedulerBinding.handleDrawFrame
package:flutter/…/scheduler/binding.dart:1104
#159    SchedulerBinding._handleDrawFrame
package:flutter/…/scheduler/binding.dart:1015
#160    _invoke (dart:ui/hooks.dart:148:13)
#161    PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:318:5)

This is the screen I am printing from:

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

  @override
  _TestViewState createState() => _TestViewState();
}

class _TestViewState extends State<TestView> {
  late final FirebaseCloudStorage _groupUsersService;
  String get userId => AuthService.firebase().currentUser!.id;   // this is how I get the current logged in users userId

  @override
  void initState() {
    _groupUsersService = FirebaseCloudStorage();

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    print(_groupUsersService.printData());     // THIS IS THE PRINT STATEMENT
    return Scaffold(
      appBar: AppBar(
        title: const Text('All users in my group'),
        // ignore: prefer_const_literals_to_create_immutables
        actions: [
          // ignore: prefer_const_constructors
          IconButton(
            onPressed: null,
            icon: const Icon(Icons.add),
          ),
        ],
      ),
      body: StreamBuilder(
        stream: _groupUsersService.getAllUsersInMyGroup(userId: userId),
        builder: (context, snapshot) {
          switch (snapshot.connectionState) {
            case ConnectionState.waiting:
            case ConnectionState.active:
              if (snapshot.hasData) {
                final allUsers = snapshot.data as Iterable<CloudGroupUser>;
                return GroupUserListView(
                  cloudUsers: allUsers,
                  // onDeleteJob: (job) async {
                  //   await _groupUsersService.deleteJob(documentId: job.documentId);
                  // },
                  onTap: (job) {
                    Navigator.of(context).pushNamed(
                      newJobRoute,
                      arguments: job,
                    );
                  },
                );
              } else {
                return const CircularProgressIndicator();
              }
            default:
              return const CircularProgressIndicator();
          }
        },
      ),
    );
  }
}

i removed the print statment from the view for the info below ( it still dont work)

I even tried to make it async ::

 

 printData() async {
    var arr = [];
    await groupUser.snapshots().listen((data) {
      data.docs.forEach((element) {
        //print(element['Group id']);
        arr.add(element['Group id']);
      });
    });

    print(arr.first);
  }



Restarted application in 525ms.
D/EGL_emulation( 4267): app_time_stats: avg=763.88ms min=17.12ms max=2249.43ms count=3
E/flutter ( 4267): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Bad state: No element
E/flutter ( 4267): #0      List.first (dart:core-patch/growable_array.dart:343:5)
E/flutter ( 4267): #1      FirebaseCloudStorage.printData
package:ijob_clone_app/…/cloud/firebase_cloud_storage.dart:88
E/flutter ( 4267): <asynchronous suspension>
E/flutter ( 4267):
W/DynamiteModule( 4267): Local module descriptor class for com.google.android.gms.providerinstaller.dynamite not found.
I/DynamiteModule( 4267): Considering local module com.google.android.gms.providerinstaller.dynamite:0 and remote module com.google.android.gms.providerinstaller.dynamite:0
W/ProviderInstaller( 4267): Failed to load providerinstaller module: No acceptable module com.google.android.gms.providerinstaller.dynamite found. Local version is 0 and remote version is 0.
D/TrafficStats( 4267): tagSocket(141) with statsTag=0xffffffff, statsUid=-1

==============+======================

I tried the following as well and got this error

  printData() async {
    var arr = [];
    await groupUser.snapshots().listen((data) {
      data.docs.forEach((element) {
        //print(element['Group id']);
        arr.add(element.data()['Group id']);
      });
    });

    print(arr.first);
  }

the code on the view was changed to the following::

  @override
  Widget build(BuildContext context) {
    _groupUsersService.printData(); 

this is the error I got

Restarted application in 558ms.
D/EGL_emulation( 4267): app_time_stats: avg=600.59ms min=20.48ms max=1754.64ms count=3
E/flutter ( 4267): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Bad state: No element
E/flutter ( 4267): #0      List.first (dart:core-patch/growable_array.dart:343:5)
E/flutter ( 4267): #1      FirebaseCloudStorage.printData
package:ijob_clone_app/…/cloud/firebase_cloud_storage.dart:98
E/flutter ( 4267): <asynchronous suspension>
E/flutter ( 4267):
W/DynamiteModule( 4267): Local module descriptor class for com.google.android.gms.providerinstaller.dynamite not found.
I/DynamiteModule( 4267): Considering local module com.google.android.gms.providerinstaller.dynamite:0 and remote module com.google.android.gms.providerinstaller.dynamite:0
W/ProviderInstaller( 4267): Failed to load providerinstaller module: No acceptable module com.google.android.gms.providerinstaller.dynamite found. Local version is 0 and remote version is 0.
D/TrafficStats( 4267): tagSocket(123) with statsTag=0xffffffff, statsUid=-1
W/System  ( 4267): Ignoring header X-Firebase-Locale because its value was null.
D/TrafficStats( 4267): tagSocket(121) with statsTag=0xffffffff, statsUid=-1
D/FirebaseAuth( 4267): Notifying id token listeners about user ( U8EZAjrCWQRvll6CVmI6OpGZwcH3 ).

3

Answers


  1. Chosen as BEST ANSWER

    I was looking for something like this

     Future getAllUsersInManagersGroup(String userId) async {
        //* managersGroupId: group id to which manager belongs to
        //* allGroupUsersDocs: all GroupUser docs
        //* allUserGroups: all GroupUsers in a List form
        //* usersInManagersGroup: all users in managers group
        // assumption: manager can only be in one group
        String? managersGroupId;
        final allGroupUsersDocs = await groupUser.get();
        final allUserGroups = allGroupUsersDocs.docs.map((e) => e.data()).toList();
        for (var user in allUserGroups) {
          if (user['User id'] == userId) {
            managersGroupId = user['Group id'];
            break;
          }
        }
        if (managersGroupId == null) return null;
        var usersInManagersGroup = [];
        for (var user in allUserGroups) {
          if (user['Group id'] == managersGroupId) {
            usersInManagersGroup.add(user['User id']);
          }
        }
    
        
        return usersInManagersGroup;
      }
    
    
    

  2. You should be using element.data()['Group id'] instead of element['Group id'].

    Happy coding 🙂

    Login or Signup to reply.
  3. .onSnapshot() is an asynchronous observer. It returns a generic object with connection. First check are data he requests exits, then assign it somewhere or don’t use snapshot, use simple .get() method. Unfortunately, I cannot help you more because I’m not a swift/flutter programmer.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search