我有两个要从中检索数据的集合:User集合和Review集合。我在Review集合中有一个“ user_id”字符串,该字符串引用了用户文档ID。
我正在检索Review数据,然后尝试检索User数据并合并两者,以便使用User的名称。
我有一个Firestore提供程序类,一个Review Bloc和一个User Bloc。代码如下:
firestore_provider.dart
static FirestoreProvider instance = FirestoreProvider();
Firestore _firestore = Firestore.instance;
Future<List<Review>> retrieveAllReviewsByProductId(String productId) async {
final List<Review> reviewList = [];
final QuerySnapshot result = await _firestore
.collection('reviews')
.where('product_id', isEqualTo: productId)
.getDocuments();
final List<DocumentSnapshot> docs = result.documents;
if (docs.length > 0) {
docs.forEach((review) {
_firestore
.collection('users')
.document(review.data['user_id'])
.get()
.then((user) {
reviewList.add(Review(
id: review.documentID,
user: user.data['username'],
body: review.data['body'],
score: double.parse(review.data['score'])));
});
});
}
return reviewList;
}
review_bloc.dart
final _reviews = PublishSubject<List<Review>>();
Observable<List<Review>> get allReviewsForProduct => _reviews.stream;
retrieveReviewsForProduct(String productId) async {
final List<Review> reviewList = await FirestoreProvider.instance
.retrieveAllReviewsByProductId(productId);
_reviews.sink.add(reviewList);
}
product_review_card.dart
class ProductReviewCard extends StatelessWidget {
@override
Widget build(BuildContext context) {
ReviewBloc reviewBloc = BlocProvider.of<ReviewBloc>(context);
// reviewBloc.retrieveReviewsForProduct(productId)
return CardBase(
child: StreamBuilder<List<Review>>(
stream: reviewBloc.allReviewsForProduct,
builder: (context, AsyncSnapshot<List<Review>> snapshot) {
if (snapshot.hasData) {
return Material(child: _buildReviews(snapshot.data));
} else if (snapshot.hasError) {
return Text('Failed ${snapshot.error}');
}
return Center(child: CircularProgressIndicator());
},
),
);
}
Widget _buildReviews(List<Review> reviews) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
children: <Widget>[
Text(
'Reviews',
style: TextStyle(
fontSize: AppConstants.PRODUCT_REVIEW_TITLE_FONT_SIZE,
fontWeight: FontWeight.bold),
),
],
mainAxisAlignment: MainAxisAlignment.spaceBetween,
),
SizedBox(height: 20),
Column(
children:
reviews.map((review) {
return UserReview(review: review);
}).toList(),
),
],
);
}
}
我希望检索用户并将其注入到Review模型对象中,但会收到错误消息
I/flutter (14653): retrieved all products: (AxFHaKkQJmSDBoEDT6Qe, HutbbzH1mwdAAy3OVzW5, zHUx3c4dG9GTYUxjMWTJ)
I/flutter (14653): retrieved all products: (AxFHaKkQJmSDBoEDT6Qe, HutbbzH1mwdAAy3OVzW5, zHUx3c4dG9GTYUxjMWTJ)
E/flutter (14653): [ERROR:flutter/shell/common/shell.cc(184)] Dart Error: Unhandled exception:
E/flutter (14653): NoSuchMethodError: The method '[]' was called on null.
E/flutter (14653): Receiver: null
E/flutter (14653): Tried calling: []("username")
E/flutter (14653): #0 Object.noSuchMethod (dart:core/runtime/libobject_patch.dart:50:5)
E/flutter (14653): #1 FirestoreProvider.retrieveAllReviewsByProductId.<anonymous closure>.<anonymous closure>
package:tokd/…/providers/firestore_provider.dart:100
E/flutter (14653): #2 _RootZone.runUnary (dart:async/zone.dart:1379:54)
E/flutter (14653): #3 _FutureListener.handleValue (dart:async/future_impl.dart:129:18)
E/flutter (14653): #4 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:642:45)
E/flutter (14653): #5 Future._propagateToListeners (dart:async/future_impl.dart:671:32)
E/flutter (14653): #6 Future._complete (dart:async/future_impl.dart:476:7)
E/flutter (14653): #7 _SyncCompleter.complete (dart:async/future_impl.dart:51:12)
E/flutter (14653): #8 _AsyncAwaitCompleter.complete (dart:async/runtime/libasync_patch.dart:28:18)
E/flutter (14653): #9 _completeOnAsyncReturn (dart:async/runtime/libasync_patch.dart:295:13)
E/flutter (14653): #10 DocumentReference.get (file:///home/stephen/flutter/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.9.0/lib/src/document_reference.dart)
E/flutter (14653): <asynchronous suspension>
E/flutter (14653): #11 FirestoreProvider.retrieveAllReviewsByProductId.<anonymous closure>
package:tokd/…/providers/firestore_provider.dart:96
E/flutter (14653): #12 List.forEach (dart:core/runtime/libgrowable_array.dart:278:8)
E/flutter (14653): #13 FirestoreProvider.retrieveAllReviewsByProductId
package:tokd/…/providers/firestore_provider.dart:92
E/flutter (14653): #14 _RootZone.runUnary (dart:async/zone.dart:1379:54)
E/flutter (14653): #15 _FutureListener.handleValue (dart:async/future_impl.dart:129:18)
E/flutter (14653): #16 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:642:45)
E/flutter (14653): #17 Future._propagateToListeners (dart:async/future_impl.dart:671:32)
E/flutter (14653): #18 Future._complete (dart:async/future_impl.dart:476:7)
E/flutter (14653): #19 _SyncCompleter.complete (dart:async/future_impl.dart:51:12)
E/flutter (14653): #20 _AsyncAwaitCompleter.complete (dart:async/runtime/libasync_patch.dart:28:18)
E/flutter (14653): #21 _completeOnAsyncReturn (dart:async/runtime/libasync_patch.dart:295:13)
E/flutter (14653): #22 Query.getDocuments (file:///home/stephen/flutter/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.9.0/lib/src/query.dart)
E/flutter (14653): #23 _RootZone.runUnary (dart:async/zone.dart:1379:54)
E/flutter (14653): #24 _FutureListener.handleValue (dart:async/future_impl.dart:129:18)
E/flutter (14653): #25 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:642:45)
E/flutter (14653): #26 Future._propagateToListeners (dart:async/future_impl.dart:671:32)
E/flutter (14653): #27 Future._complete (dart:async/future_impl.dart:476:7)
E/flutter (14653): #28 _SyncCompleter.complete (dart:async/future_impl.dart:51:12)
E/flutter (14653): #29 _AsyncAwaitCompleter.complete (dart:async/runtime/libasync_patch.dart:28:18)
E/flutter (14653): #30 _completeOnAsyncReturn (dart:async/runtime/libasync_patch.dart:295:13)
E/flutter (14653): #31 MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart)
E/flutter (14653): #32 _RootZone.runUnary (dart:async/zone.dart:1379:54)
E/flutter (14653): #33 _FutureListener.handleValue (dart:async/future_impl.dart:129:18)
Flutter Doctor表现良好
flutter doctor -v
[✓] Flutter (Channel stable, v1.0.0, on Linux, locale en_CA.UTF-8)
• Flutter version 1.0.0 at /home/stephen/flutter
• Framework revision 5391447fae (10 weeks ago), 2018-11-29 19:41:26 -0800
• Engine revision 7375a0f414
• Dart version 2.1.0 (build 2.1.0-dev.9.4 f9ebf21297)
[✓] Android toolchain - develop for Android devices (Android SDK 28.0.3)
• Android SDK at /home/stephen/Android/Sdk
• Android NDK location not configured (optional; useful for native profiling
support)
• Platform android-28, build-tools 28.0.3
• Java binary at: /home/stephen/android-studio/jre/bin/java
• Java version OpenJDK Runtime Environment (build
1.8.0_152-release-1248-b01)
• All Android licenses accepted.
[✓] Android Studio (version 3.3)
• Android Studio at /home/stephen/android-studio
• Flutter plugin version 32.0.1
• Dart plugin version 182.5124
• Java version OpenJDK Runtime Environment (build
1.8.0_152-release-1248-b01)
[✓] VS Code (version 1.30.2)
• VS Code at /usr/share/code
• Flutter extension version 2.22.3
[✓] Connected device (1 available)
• Android SDK built for x86 • emulator-5554 • android-x86 • Android 9 (API
28) (emulator)
• No issues found!