I have two collections::
- group
- group users
The group users collection has documents …
Each document has two fields
- Group id
- User id
The group collection has documents …
Each document has two fields
- Group manager id
- Group name
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
I was looking for something like this
You should be using
element.data()['Group id']
instead ofelement['Group id']
.Happy coding 🙂
.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.