我有一个名为“汽车”的收藏和一个“用户”收藏。 每个“用户”文档都包含汽车参考列表。
我尝试了多种方法来获取用户在其文档中拥有的所有“汽车”文档流。 “ myCars”列表。
我的问题是myCar列表更改时,StreamBuilder中的流没有更新。
下面将描述我当前的代码。
我还尝试通过使用“ whereIn”运算符和带有cars doc id的数组查询“ car”集合来获取所有“ car”文档。这也起作用,但是firestore仅允许在“ whereIn”运算符中输入10个条目,这对我来说不起作用。用户的列表中可以包含10个以上的条目。
我觉得我没有以正确的方式创建车流。 我的数据模型不是针对这种情况的最佳实践设置的,还是在Firestore中缺少查询功能?
汽车收藏
{
"docId": 123,
"carName": "volvo",
"rating": 6.3
}
用户集合
{
userId: "userIdField",
myCars: [
{
"carDoc": 123,
"favourite": true
},
{
"carDoc": 124,
"favourite": true
},
{
"carDoc": 125,
"favourite": false
}
]
}
我具有用于提取用户流的功能
Stream<User> fetchUser(String uid) {
return FirebaseFirestore.instance.collection(USER_COLLECTION)
.doc(uid)
.get()
.asStream()
.map((event) {
if (event.data().isNotEmpty) {
var user = new User();
user.userId = uid;
user.carDocs = List.from((event.data()['carDoc'])
.map((e) => User(e['carDoc'] as DocumentReference, e['favourite'] as bool)));
return user;
} else {
return null;
}
}
);
}
我这样创建小部件。
child: Container(
child: StreamBuilder(
stream: userService.fetchUser(user.uid),
builder: (context, AsyncSnapshot<User> user) {
if (!user.hasData) {
return Text("meh");
}
return FutureBuilder(
future: Future.wait(user.data.myCars.map((e) => e.carDoc.get()).toList()),
builder: (context, AsyncSnapshot<List<DocumentSnapshot>> dss) {
if (!dss.hasData) {
return Text("next meh");
}
return ListView(
children: _build(dss.data.map((e) => createCarWidgtItem(e)).toList()),
);
},
);
},
),
)
答案 0 :(得分:0)
如果我忽略流和语言的观点,而专注于数据库结构,希望您不要介意。
当我查看它时,我想到以关系/ SQL方式使用NoSQL数据库。这意味着一个馆藏与其他馆藏有关系。在这种情况下,我认为PostgreSQL会更好,Cloud SQL的GCP上也可以使用PostgreSQL。
另一方面,也许最好将myCars
字段(当前是一个数组)(至少看起来像表单描述)更改为子集合,其中每个用户将拥有完整的汽车对象。
我知道解决方案是多余的(意味着许多用户可以在自己的收藏夹中拥有相同的汽车),但这就是NoSQL数据库的想法。数据是多余的,但是您可以将所有内容都放在一个地方,而不必通过所有集合查询。
在上述示例中,您无需构建复杂的查询即可获得用户喜欢的汽车的列表(请将其视为伪代码):
FirebaseFirestore.instance.collection(USER_COLLECTION)
.doc(uid)
.collection('myCars')
.where("faviorite", isEqualTo: true)
.get()
或者甚至您只能在用户myCars
集合中存储喜欢的汽车,而您可以忽略where
方法和favorite
布尔字段。