flutterfire
flutterfire copied to clipboard
🐛 [cloud_firestore_odm] Required data thrown exception although not expected
Bug report
As per the examples, checks for snapshot.hasError and !snapshot.hasData is already done before using the data. But still I get the below exception which checks for error and data.
My understanding is that it shouldn't be reached to call snapshot.requireData due to validations in previous lines.
return FirestoreBuilder<AppUserQuerySnapshot>(
ref: usersRef
.orderById()
.orderByJoinDate(descending: true)
.whereIsActive(isEqualTo: true)
.whereId(isNotEqualTo: FirebaseAuth.instance.currentUser?.uid),
builder: (context, AsyncSnapshot<AppUserQuerySnapshot> snapshot,
Widget? child) {
if (snapshot.hasError) {
return Container(
height: 0,
);
}
if (!snapshot.hasData) {
const Center(
child: CircularProgressIndicator.adaptive(),
);
}
AppUserQuerySnapshot querySnapshot = snapshot.requireData;
List<Widget> usersList = querySnapshot.docs.map((e) {
AppUser user = e.data;
return InkWell(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: AppUserAvatar(user),
),
onTap: () => context.push('/profile/${user.id}'),
);
}).toList();
return ListView(
scrollDirection: Axis.horizontal,
children: usersList,
);
},
);
Error which I am getting for a brief moment before rendering the actual content is given below.
======== Exception caught by widgets library =======================================================
The following StateError was thrown building FirestoreBuilder<AppUserQuerySnapshot>(dirty, state: _FirestoreBuilderState<AppUserQuerySnapshot>#924ce):
Bad state: Snapshot has neither data nor error
The relevant error-causing widget was:
FirestoreBuilder<AppUserQuerySnapshot> FirestoreBuilder:file:///D:/flutter/mozhli/lib/ui/home/widgets/recent_users_widget.dart:14:12
When the exception was thrown, this was the stack:
#0 AsyncSnapshot.requireData (package:flutter/src/widgets/async.dart:255:5)
#1 RecentUsersWidget.build.<anonymous closure> (package:mozhli/ui/home/widgets/recent_users_widget.dart:35:55)
#2 _FirestoreBuilderState.build (package:cloud_firestore_odm/src/firestore_builder.dart:133:26)
#3 StatefulElement.build (package:flutter/src/widgets/framework.dart:4992:27)
#4 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4878:15)
#5 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5050:11)
#6 Element.rebuild (package:flutter/src/widgets/framework.dart:4604:5)
#7 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:4859:5)
#8 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:5041:11)
#9 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4853:5)
... Normal element mounting (10 frames)
#19 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3863:16)
#20 MultiChildRenderObjectElement.inflateWidget (package:flutter/src/widgets/framework.dart:6435:36)
#21 MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:6447:32)
... Normal element mounting (25 frames)
#46 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3863:16)
#47 MultiChildRenderObjectElement.inflateWidget (package:flutter/src/widgets/framework.dart:6435:36)
#48 MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:6447:32)
... Normal element mounting (135 frames)
#183 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3863:16)
Expected behavior
If no data, progress indicator should be shown. IF error, widget should not be shown.
Flutter doctor
Run flutter doctor and paste the output below:
Click To Expand
C:\Users\Purus>flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, 3.3.2, on Microsoft Windows [Version 10.0.22000.978], locale en-IN)
Checking Android licenses is taking an unexpectedly long time...[√] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
[√] Chrome - develop for the web
[√] Visual Studio - develop for Windows (Visual Studio Community 2022 17.3.0)
[√] Android Studio (version 2021.2)
[√] IntelliJ IDEA Community Edition (version 2022.2)
[√] VS Code (version 1.71.0)
[√] Connected device (4 available)
[√] HTTP Host Availability
• No issues found!
C:\Users\Purus>
Flutter dependencies
Run flutter pub deps -- --style=compact and paste the output below:
Click To Expand
C:\Users\Purus>flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, 3.3.2, on Microsoft Windows [Version 10.0.22000.978], locale en-IN)
Checking Android licenses is taking an unexpectedly long time...[√] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
[√] Chrome - develop for the web
[√] Visual Studio - develop for Windows (Visual Studio Community 2022 17.3.0)
[√] Android Studio (version 2021.2)
[√] IntelliJ IDEA Community Edition (version 2022.2)
[√] VS Code (version 1.71.0)
[√] Connected device (4 available)
[√] HTTP Host Availability
• No issues found!
C:\Users\Purus>
It'd help if you could share a complete example, or give more info (like sharing the AsyncSnapshot).
Otherwise I doubt we can do anything to help here, as it's unclear what happens.
This is my model. Hope this is helpful. Not sure what you meant by AsyncSnapshot.
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:cloud_firestore_odm/cloud_firestore_odm.dart';
import 'package:equatable/equatable.dart';
import 'package:json_annotation/json_annotation.dart';
part 'app_user.g.dart';
const fireStoreSerializable = JsonSerializable(
converters: firestoreJsonConverters,
explicitToJson: true,
createFieldMap: true,
);
@fireStoreSerializable
class AppUser extends Equatable {
const AppUser({
required this.id,
required this.name,
required this.email,
required this.photoUrl,
required this.joinDate,
this.birthDate,
this.country,
this.age = 0,
this.isOnline = false,
this.lastOnline,
this.isAdmin = false,
this.isActive = true,
this.gender,
this.tokens,
});
final String id;
final String name;
final String email;
final String photoUrl;
final Timestamp joinDate;
final Timestamp? birthDate;
final int age;
final bool? isAdmin;
final bool? isOnline;
final Timestamp? lastOnline;
final bool? isActive;
final String? country;
final String? gender;
final List<String>? tokens;
factory AppUser.fromJson(Map<String, Object?> json) =>
_$AppUserFromJson(json);
Map<String, Object?> toJson() => _$AppUserToJson(this);
@override
List<Object?> get props => [name, email, photoUrl];
}
@Collection<AppUser>('users')
// @Collection<AppUser>('users/*/friends')
final usersRef = AppUserCollectionReference();
May I know if this is confirmed to a bug or an issue at my end? Other use cases of ODM seems to work fine for me.
Hard to say. What you shared still isn't something we can run to reproduce the problem on our end, and you haven't shared your AsyncSnapshot as requested.
We'd need a complete example, with steps to reproduce and data.
To begin with, the source code of requireData is the following:
T get requireData {
if (hasData) {
return data!;
}
if (hasError) {
Error.throwWithStackTrace(error!, stackTrace!);
}
throw StateError('Snapshot has neither data nor error');
}
So you're describing is not possible and there's likely more to it. But I can't guess what the problem is with the information given.
Yea, I understand the problem of debugging the issue without actual example. My project is quite unorganized now and hard to seperate the issue.
For now, I have made the below changes as the connection state is still loading when the issue occurs. So to avoid, have put the below check. I can close this issue as this could be due to something I have done from my end.
if (snapshot.data?.docs.isEmpty ?? true) {
return const Padding(
padding: EdgeInsets.only(top: 8.0),
child: Text('No users yet. Please come back.'),
);
}
AppUserQuerySnapshot querySnapshot = snapshot.requireData;