gpt4 book ai didi

flutter - 如何从Firestore制作父/子对象流

转载 作者:行者123 更新时间:2023-12-03 03:12:13 25 4
gpt4 key购买 nike

我有一个具有分层关系的Firestore数据库。 “父”文档具有子对象的集合(“子”)。我想提出家长反对意见。因此,如果父级在Fire store中发生更改,则流应提供一个加载了所有子级的新Parent对象。

下面的代码是我想要实现的。问题出在标记为“====>问题”的行中,该行已插入代码中。

编译器说:返回类型'List>'不是一个'List',如匿名closure.dart(return_of_invalid_type_from_closure)所定义。

我不知道如何将此流转换为“映射”调用,以异步方式获取列表而不是 future

有人知道Flutter / Dart中分层Firestore数据的好样本吗?

import 'package:cloud_firestore/cloud_firestore.dart';

final parentsCollection = Firestore.instance.collection('parents');

Stream<List<Parent>> jots() {
return parentsCollection.snapshots().map((snapshot) {

//====================================================
return snapshot.documents // <===== Problem
//====================================================
.map((doc) async {
var parentEntity = await ParentEntity.fromSnapshot(doc);
return Parent.fromEntity(parentEntity);
}).toList();
});
}

class Parent {
final String id;
final String data;
final List<Child> children ;

Parent(this.data, {
String id,
List<Child> children
})
: this.id = id ?? '',
this.children = children ?? List<Child>()
;

static Parent fromEntity(ParentEntity entity) {
var parent = Parent(
entity.data,
id: entity.id,
children: entity.children.map((c)=>Child.fromEntity(c))
);
return parent;
}
}

class Child {
final String id;
final String label;

Child(this.label, {String id})
: this.id = id ?? '';

static Child fromEntity(ChildEntity entity) {
var child = Child(
entity.label,
id: entity.id,
);
return child;
}
}

class ParentEntity {
final String id;
final String data;
final List<ChildEntity> children;

ParentEntity( this.id, this.data, this.children );

static Future<ParentEntity> fromSnapshot(DocumentSnapshot snapshot) async {
var children = await _childrenFromSnapshot(snapshot);
return ParentEntity(
snapshot.documentID,
snapshot.data['data'],
children
);
}

static Future<List<ChildEntity>> _childrenFromSnapshot(
DocumentSnapshot snapshot) async {
var childCollection = snapshot.reference.collection("children");
QuerySnapshot docs = await childCollection.getDocuments();
return docs.documents.map((doc) {
return ChildEntity( doc.documentID, doc.data["label"]);
});
}
}

class ChildEntity {
final String id;
final String label;

ChildEntity( this.id, this.label );

static ChildEntity fromSnapshot(DocumentSnapshot snapshot) {
return ChildEntity(
snapshot.documentID,
snapshot.data['label']);
}
}

最佳答案

我认为这是您要的:

Stream<List<Parent>> jots2() {
return parentsCollection.snapshots().asyncMap((snapshot) async {
return Future.wait(snapshot.documents.map((doc) async {
var parentEntity = await ParentEntity.fromSnapshot(doc);
return Parent.fromEntity(parentEntity);
}).toList());
});
}

诀窍是使用 asyncMap(类似于map,但异步)和 Future.wait(等待所有Future完成)异步处理QuerySnapshot。

一些注意事项:
  • 您可能在所有.toList()后都缺少.map
  • 使用此方法,如果仅更改子代的值,则流不会发出新值,但是如果您更新父代
  • ,它会发送更新的子代
  • ,因为您总是以这种方式读取父级的完整子级集合,这可能会影响Firestore的使用,因为它是基于每个文档的

    您还要求提供“好”样本。不幸的是-这取决于您的数据和应用程序。 Firebase编写了关于结构化数据的whole page。有时最好避免使用子集合,有时则要避免。

    在您的情况下,将“ child ”作为数据字段(children2)而不是子集合似乎更有意义,但是我不完全知道您在创建什么。

    Firestore panel

  • 关于flutter - 如何从Firestore制作父/子对象流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58979765/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com