How can I make a stream of parent/child objects from firestore

thrag

I have a firestore database with a hierarchical relationship. The "Parent" document has a collection ("children") of child objects. I want to have a stream of Parent objections. So if the parent changes in Fire store the stream should offer a new Parent object with all the children loaded.

The code below is what I am trying to achieve. The problem is in the line marked "====> Problem", which in inserted into the code.

The compiler says : The return type 'List>' isn't a 'List', as defined by anonymous closure.dart(return_of_invalid_type_from_closure).

I don't know how to convert this stream to "map" call to an asyn call to get a List instead of a Future

Anyone know a good sample for hierarchical Firestore data in Flutter/Dart?

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']);
  }
}
pr0gramist

I think this is what you are asking for:

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());
  });
}

The trick is to use asyncMap (which is like map, but async) and Future.wait (which waits for all Futures to complete) to asynchronously process QuerySnapshot.

Few notes:

  • you're probably missing .toList() after all .map
  • using this method your Stream won't emit new value if only value of the children is changed, but it does send updated children if you update the parent
  • because this way you always read full children collection of the parent this may impact your Firestore usage as it is per document basis

Você também pediu uma amostra "boa". Infelizmente - isso depende de seus dados e aplicativo. O Firebase criou uma página inteira sobre estruturação de dados. Às vezes é melhor evitar subcoleções, às vezes não.

Parece que, no seu caso, ter seus "filhos" como campo de dados (filhos2) em vez de subcoleção faz mais sentido, mas não sei exatamente o que você está criando.

Painel Firestore

Este artigo é coletado da Internet.

Se houver alguma infração, entre em [email protected] Delete.

editar em
0

deixe-me dizer algumas palavras

0comentários
loginDepois de participar da revisão

Artigos relacionados

How can I create a stream of <Interface> objects?

How can I make a generic function that prints to any output stream?

How can I make Objects communicate with each other in Python?

How can I make an array from a variable?

Return a list of objects from firestore only once, NOT a stream. In Flutter

How can I deal with the firestore whereIn limit of 10 when using a switch stream?

How can I get specific document data from firestore querysnapshot?

Firestore! How can I remove a map from array by javascript code?

How can I get whole (selected) objects from multiselect - Angular

How can I access objects from nested lists with a loop

How can I concatenate objects from a string with a semicolon in between?

when i make a $group how can i return the total sum of a property present in all objects?

How can I make sublists from a list based on strings in python?

How can I make a marker for each user getting from the database?

How can I make the system empty value from the guid null?

How can I make objects permanently stick in window without being refreshed in Pygame?

How can I make slot to be filled with multiple same-type objects in R?

How can I make SWIG return unicode objects for strings in Python 2?

How can I make a shader that makes the intersection of two 3D objects transparent?

Can't combine firestore stream

How can i import JSON into Cloud Firestore

How can I test if a document in firestore exists?

How deep can I perform the Firestore Queries

How can I enforce database schema in Firestore?

How can I stream arrays with Grpc?

How can I get Timestamp from Firestore server without bothering for the case when device clock is out of sync with Firestore

VueJs, Vuefire, Firestore: How can I filter a synched Firestore document

how can i throttle a stream of values added to a BehaviourSubject stream with next?

How to i make "rows" consiting of pairs from a list of objects that is sorted based on their attributes

TOP lista

quentelabel

Arquivo