Флаттер firebase_database получить детей - PullRequest
0 голосов
/ 15 февраля 2019

Привет! Я хочу десериализовать снимок из базы данных реального времени в объект Company и добавить его в список _companies .Но я продолжаю получать сообщение об ошибке ...

Это то, что у меня есть до сих пор:

  List<Company> _companies = [];
  @override
  void initState() {
    // TODO: implement initState
    super.initState();

    getItems().then((list){
      print("Now the list is here");

      setState(() {
        for (int i=0; i < list.length; i++) {
          Map<String, dynamic> map = list[i];

          Company company = new Company.fromMap(map);
          _companies.add(company);
        }
      });

    });
  }

  static Future<List> getItems( ) async {
    Completer<List> completer = new Completer<List>();

    FirebaseDatabase.instance
        .reference()
        .child("Companies")
        .once()
        .then( (DataSnapshot snapshot) {

      List map = snapshot.value; //It fails here
      completer.complete(map);
    } );

    return completer.future;
  }

Это класс моей компании:

class Company {
  String key;
  String category;
  String company_name;
  String company_url;
  String country;
  String description;
  String email;
  String faq_url;
  String instagram_url;
  String logo_url_image;
  String p_category;
  String parent_company_ok;
  String timestamp;

  Company();

  Company.fromSnapshot(DataSnapshot snapshot)
      : key = snapshot.key,
      category = snapshot.value['category'],
      company_name = snapshot.value['company_name'],
      company_url = snapshot.value['company_url'],
      country = snapshot.value['country'],
      description=  snapshot.value['description'],
      email = snapshot.value['email'],
      faq_url = snapshot.value['faq_url'],
      instagram_url = snapshot.value['instagram_url'],
      logo_url_image = snapshot.value['logo_url_image'],
      p_category = snapshot.value['p_category'],
      parent_company_ok = snapshot.value['parent_company_ok'],
      timestamp = snapshot.value['timestamp'];
}

Как всегда,происходит сбой в getItems () в List map = snapshot.value;.С исключением: _InternalLinkedHashMap<dynamic, dynamic>' is not a subtype of type 'List<dynamic>'

Также, если кто-то может предоставить код для отображения детей в виджете списка, я был бы очень рад:)

Вот моя структура данных в базе данных реального времени firebase:

enter image description here

Ответы [ 2 ]

0 голосов
/ 16 февраля 2019

Ну, а в сообщении об ошибке говорится, что snapshot.value - это не список, а карта, поэтому строка List map = snapshot.value; всегда будет неудачной.Поскольку вы читаете дерево узлов компаний из вашей базы данных, будет возвращена карта карт, что-то вроде Map<String, Map<dynamic,dynamic>> со всеми данными из соответствующего узла.Я предоставлю вам функцию, которая будет анализировать ваши данные Json в объекте Company, и я оставлю некоторые комментарии в исходном коде, чтобы попытаться объяснить вам процесс.Это просто.

List<Company> _parseData(DataSnapshot dataSnapshot) {
    List<Company> companyList =new List();

    // here you replace List map = snapshot.value with...
    Map<String, dynamic> mapOfMaps = Map.from( dataSnapshot.value );
    //actually dynamic here is another Map, String are the keys like -LXuQmyuF7E... or LXuSkMdJX... 
   //of your picture example and dynamic other Map    

    //in next lines we will interate in all values of your map
    //remeber that the values are maps too, values has one map for each company. 
    //The values are Map<String, dynamic>
    //in this case String are keys like category, company_name, country, etc... 
    //and dynamics data like string, int, float, etc

    //parsing and adding each Company object to list
    mapOfMaps.values.forEach( (value) {
      companyList.add(
          //here you'll not use fromSnapshot to parse data,
          //i thing you got why we're not using fromSnapshot
          Company.fromJson( Map.from(value) )
      );
    });

    return companyList;

  }

Обратите внимание, что вы будете использовать Company.fromSnapshot (снимок), когда читаете конкретную компанию из вашей базы данных, что-то вроде ...

// just to illustrate
var snapshot = await FirebaseDatabase.instance
      .reference()
      .child("Companies")
      .child(companyId).once();
Company.fromSnapshot( snapshot );

, потому что в этом случаеsnapshot.value представляет собой одну карту.Что ж, другое дело, взгляните на ваш метод initState в вашем виджете statefull, я не знаю, является ли хороший подход вызовом setState внутри метода initState даже после выполнения в будущем.Это всего лишь совет.

0 голосов
/ 15 февраля 2019

snapshot.value возвращает карту, и вы используете список для ее хранения.Возможно, самое простое решение здесь - это использовать тип var для объявления вашей переменной карты:

var map = snapshot.value;

, но хорошей практикой является установка типа, когда это возможно, для ваших переменных.Итак, в этом случае лучший вариант - установить его так:

Map<dynamic, dynamic> map = snapshot.value;

Проверьте документацию дротика, чтобы улучшить свои навыки использования карт и списка и как они работают Списки документов Карты документов

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...