Получаем с помощью Flutter вложенный JSON из Firebase DataSnapshot

#json #firebase-realtime-database #dart #flutter

#json #firebase-база данных в реальном времени #dart #flutter

Вопрос:

Я использую flutter с пакетом firebase_database. С помощью кода

 final FirebaseDatabase _database = FirebaseDatabase.instance;

@override
void initState() {
  super.initState();
  _newsList = new List();

  _newsQuery = _database
     .reference()
     .child('news')
     .orderByChild('published')
     .limitToFirst(10);

  _newsQuery.onChildAdded.listen(_onEntryAdded);
}

_onEntryAdded(Event event) {
  setState(() {
    News n = News.fromSnapshot(event.snapshot);
    _newsList.add(n);
  });
}
  

я получаю идеальный список _newsList всех запрошенных элементов. Класс news является

  import 'package:firebase_database/firebase_database.dart';

 class News {
   String key;
   String image;
   String text;
   String title;
   String published;

   News(this.image, this.text, this.published);

   News.fromSnapshot(DataSnapshot snapshot) :
     key = snapshot.key,
     text = snapshot.value["text"],
     title = snapshot.value["title"],
     image = snapshot.value["image"],
     published = snapshot.value["published"];

   toJson() {
     return {
     "image": image,
     "text": text,
     "title": title,
     "published": published,
   };
  }
}
  

Структура json в базе данных является:

 database
|__news
    |__post1
    |    |__text: "Lorem ipsum"
    |    |__title: "Title of post"
    |
    |__post2
         |__ ...
  

Теперь я хочу загрузить вложенную json-структуру из базы данных с

 database
|__news
    |__category1
    |    |
    |    |__post1
    |    |    |__text: "Lorem ipsum 1"
    |    |    |__title: "Title of post1"
    |    |__post2
    |    |    |__text: "Lorem ipsum 2"
    |    |    |__title: "Title of post2"
    |    |__description: "description text"
    |    |__id: "id of category"
    |    .
    |    .
    |
    |__category2
    |    |
    |    |__post34
    |    |    |__text: "Lorem ipsum 34"
    |    |    |__title: "Title of post34"
    |    .
    |    .
  

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

  class News {
   final List<Category> categories;

   News({this.categories});

   factory News.fromSnapshot(DataSnapshot snapshot) {

   List<dynamic> listS = snapshot.value;

   listS.forEach((value) =>
     print('V $value')
   );

   List<Category> list = listS.map((i) => Category.fromJson(i)).toList();

   return News(
     categories: list
   );

 }
  

Но это приводит к возникновению исключения

E / flutter (5882): [ОШИБКА: flutter/lib/ui/ui_dart_state.cc(148)] Необработанное исключение: тип ‘_InternalLinkedHashMap’ не является подтипом типа ‘Map’ E / flutter (5882): #0 новых новостей.из snapshot. (пакет: app /models /news.dart: 23:55) E / flutter (5882): #1 отображаемый в списке.элементАт (dart:_internal/iterable.dart:414:29) E / flutter ( 5882): # 2 отображаемый в списке.ToList (dart:_internal/iterable.dart:219:19)

Я не нашел во flutter и dart кода-примера для загрузки вложенного json с помощью DataSnapshot. Знаете ли вы какой-нибудь пример кода?

Если вы хотите увидеть мой полный код, то посмотрите наhttps://github.com/matthiaw/gbh_app. Нерабочая часть — это вложенный json в calendar на https://github.com/matthiaw/gbh_app/blob/4de0f20f6162801db86ef6644609829c27a4dd76/lib/models/calendar.dart

Комментарии:

1. Пожалуйста, добавьте образец данных, возвращенных в формате JSON, для обоих результатов запроса.

Ответ №1:

Я также изучал, как обрабатывать вложенные объекты json во Flutter с помощью Cloud Firestore, и нашел ваш пост. Поскольку я решил свою проблему, возможно, это поможет и вам: на фабрике «FromJSON» моей модели мне пришлось проанализировать каждый элемент в списке с помощью jsonEncode и jsonDecode, прежде чем добавлять его в модель.

в DatabaseService:

 Future<LocationRecordings> getLocationRecordings(String location) async {
 DocumentReference document = locationRecordingsCollection.document((location));

 DocumentSnapshot documentSnapshot =  await document.get();
 var data = LocationRecordings.fromJson(documentSnapshot.data);
 return data;
}
  

в модели:

 factory LocationRecordings.fromJson(Map<String, dynamic> json) {
 List<Recording> recList = [];

 List<dynamic>.from(json['recordings']).forEach((content) {
      Recording recording = Recording.fromJson(jsonDecode(jsonEncode(content)));
      recList.add(recording);
   });
 return new LocationRecordings(recordings: recList, state: json['state']);
}