【发布时间】:2021-08-16 21:49:21
【问题描述】:
我想在我的 Flutter 项目中将 built_value 与 cloud_firestore 结合起来。我相信这是有道理的,这就是在一个干净的世界中应该如何做到的? (见https://firebase.flutter.dev/docs/firestore/usage/#typing-collectionreference-and-documentreference)。
这是我目前为止的地方。
Place 模型:
// ../models/place.dart
import 'dart:convert';
import 'package:built_collection/built_collection.dart';
import 'package:built_value/built_value.dart';
import 'package:built_value/serializer.dart';
import 'package:sitback/models/serializers.dart';
part 'place.g.dart';
abstract class Place implements Built<Place, PlaceBuilder> {
// Fields
String? get id;
String get name;
String get address;
BuiltList<String> get methods;
Place._();
factory Place([void Function(PlaceBuilder) updates]) = _$Place;
String toJson() {
return json
.encode(standardSerializers.serializeWith(Place.serializer, this));
}
// https://github.com/google/built_value.dart/issues/964#issuecomment-850419921
static Place? fromJson(String jsonString) {
return standardSerializers.deserializeWith(
Place.serializer, json.decode(jsonString));
}
Map<String, Object?> toFirestore() {
return serializers.serializeWith(Place.serializer, this);
}
// TODO: check if something can be improved
// https://github.com/google/built_value.dart/issues/964#issuecomment-850419921
static Place? fromFirestore(Map<String, dynamic> json) {
return serializers.deserializeWith(Place.serializer, json);
}
static Serializer<Place> get serializer => _$placeSerializer;
}
在上面的代码中,我有两个问题:
A value of type 'Object?' can't be returned from the method 'toFirestore' because it has a return type of 'Map<String, Object?>'
但是,这是在多个位置(SO 问题、github 问题)提出的解决方案,所以我不明白为什么会出现该错误。
- 在相同的参考教程/视频中,他们使用
Place而不是Place?作为fromJson的返回值,但随后出现以下错误:
A value of type 'Place?' can't be returned from the method 'fromJson' because it has a return type of 'Place'
这可能与最近的零安全变化有关吗?
以下是serializers(遵循文档/教程):
// ../models/serializers.dart
library serializers;
import 'package:built_collection/built_collection.dart';
import 'package:built_value/json_object.dart';
import 'package:built_value/serializer.dart';
import 'package:built_value/standard_json_plugin.dart';
import 'package:sitback/models/place.dart';
part 'serializers.g.dart';
@SerializersFor([
Place,
])
final Serializers serializers = _$serializers;
final Serializers standardSerializers =
(_$serializers.toBuilder()..addPlugin(StandardJsonPlugin())).build();
最后,这里是我想在使用通过built_value 包定义的Place“数据类”时使用 Firestore 集合的地方:
class IndexPage extends StatelessWidget {
IndexPage({
Key? key,
}) : super(key: key);
final placesRef = FirebaseFirestore.instance
.collection('places')
.withConverter<Place>(
// TODO: ! at the end due to Place? vs Place in class definition
// would require a try-catch or something else?
fromFirestore: (snapshot, _) => Place.fromFirestore(snapshot.data()!)!,
toFirestore: (place, _) => place.toFirestore(),
);
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: StreamBuilder<QuerySnapshot<Place>>(
stream: placesRef.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
} else {
return CustomScrollView(
slivers: <Widget>[
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
final itemData = snapshot.data!.docs[index];
return PlaceCard(itemData: itemData);
},
childCount: snapshot.data!.docs.length,
),
),
],
);
}
},
),
),
);
}
}
由于这条线,它目前无法正常工作:
toFirestore: (place, _) => place.toFirestore(),。如果我从toFirestore() 返回{},那么它会编译并工作
但我怀疑 fromFirestore() 甚至都没有被调用:如果我将 assert(false); 放在函数中,什么都不会发生。除了一个例外,我会。
【问题讨论】:
标签: flutter dart google-cloud-firestore built-value