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