文档引用流未更新

时间:2020-10-01 20:49:57

标签: flutter dart google-cloud-firestore

我有一个名为“汽车”的收藏和一个“用户”收藏。 每个“用户”文档都包含汽车参考列表。

我尝试了多种方法来获取用户在其文档中拥有的所有“汽车”文档流。 “ 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()),
                    );
                },
            );
        },
    ),
)

1 个答案:

答案 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布尔字段。