Home > Software design >  How to get firebase data back in simple array
How to get firebase data back in simple array

Time:10-17

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 ).

CodePudding user response:

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

Happy coding :)

CodePudding user response:

.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.

CodePudding user response:

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;
  }


  • Related