Я использую flutter_bloc для обработки состояния в моем приложении Flutter. Я использую Firestore в качестве хранилища.
Мой вопрос:
- Каков наилучший способ хранения временных переменных и обеспечения их доступности на всех экранах?
- Предполагается ли, что, если я хочу создавать запросы Firestore с вложенными коллекциями, мне нужно передать идентификаторы документов через блок и репозиторий для создания запросов?
Как и в моем случае, мне нужно хранить идентификаторы, чтобы иметь возможность создавать запросы firestore с вложенными коллекциями в документах.
У меня есть следующая структура в firestore:
school (document)
- courses (collection)
- course1 (document)
- course2 (document)
- ...
- sections (collection)
- ...
Запросы:
Чтобы получить курсы:
Firestore.instance
.collection('schools')
.document('<school id>')
.collection("courses")
.snapshots();
Чтобы получить разделы для курса:
Firestore.instance
.collection('schools')
.document('<school id>')
.collection('courses')
.document('<course id>')
.collection('sections')
.snapshots();
Так что мне нужно как-то сохранить "идентификатор школы" и ""идентификатор курса" и передайте их в блок и хранилище для создания запроса к хранилищу.
В данный момент функция моего блока, которая загружает школу, загрузит ее из хранилища и затем сохранит ее, сериализовав в shared_preferences.
Функция, которая читает школу, будет читать ее из shared_preferences, а не из firestore после этого. Таким образом, я могу получить доступ к shared_preferences с другого экрана, когда мне нужны данные. Но почему-то это выглядит немного грязно. Я посмотрел на hydrated_bloc, который в основном делает то же самое, так что я мог бы использовать это, но он все еще чувствует себя грязно, передавая переменные через блок и репозиторий для построения запроса.
Я новичоккогда дело доходит до создания хорошей архитектуры с помощью блока, и я бы предпочел построить что-то правильное с самого начала.
Кто-нибудь знает лучший способ сделать это?
Вот мой класс репозитория,Как видите, мне нужно проанализировать идентификатор школьного документа в репозитории Firebase. На данный момент это жестко закодировано.
class FirebaseCourseRepository implements CourseRepository {
final courseCollection = Firestore.instance
.collection('school')
.document("3kRHuyk20UggHwm4wrUI") // this is where I need to pass the doc id from the bloc to.
.collection("course");
@override
Stream<List<Course>> courses() {
return courseCollection.snapshots()
.map((snapshot) {
return snapshot.documents
.map((doc) => Course.fromEntity(CourseEntity.fromSnapshot(doc)))
.toList();
});
}
@override
Future<void> addCourse(Course course) {
return courseCollection.add(course.toEntity().toDocument());
}
@override
Future<void> updateCourse(Course updatedCourse) {
return courseCollection
.document(updatedCourse.id)
.updateData(updatedCourse.toEntity().toDocument());
}
@override
Future<void> deleteCourse(Course course) async {
return courseCollection.document(course.id).delete();
}
}
А вот и блок. Я действительно не знаю, как я могу передать идентификатор документа в хранилище только один раз.
class CourseBloc extends Bloc<CourseEvent, CourseState> {
final CourseRepository _courseRepository;
StreamSubscription _courseSubscription;
// Repository is injected through constructor, so that it can
// be easily tested.
CourseBloc({@required CourseRepository courseRepository})
: assert(courseRepository != null),
_courseRepository = courseRepository;
@override
get initialState => CourseInitState();
@override
Stream<CourseState> mapEventToState(CourseEvent event) async* {
if(event is LoadCoursesEvent) {
yield* _mapLoadCoursesToState(event);
} else if(event is CoursesLoadedEvent) {
yield* _mapCoursesLoadedToState(event);
} else if(event is AddCourseEvent) {
yield* _mapAddCourseToState(event);
} else if(event is UpdateCourseEvent) {
yield* _mapUpdateCourseToState(event);
} else if(event is DeleteCourseEvent) {
yield* _mapDeleteCourseToState(event);
}
}
// Load all courses
Stream<CourseState> _mapLoadCoursesToState(LoadCoursesEvent event) async* {
yield CoursesLoadingState();
_courseSubscription?.cancel();
_courseSubscription = _courseRepository.courses().listen(
(courses) {
dispatch(
CoursesLoadedEvent(courses),
);
},
);
}
Stream<CourseState> _mapCoursesLoadedToState(CoursesLoadedEvent event) async* {
yield CoursesLoadedState(event.courses);
}
Stream<CourseState> _mapAddCourseToState(AddCourseEvent event) async* {
_courseRepository.addCourse(event.course);
}
Stream<CourseState> _mapUpdateCourseToState(UpdateCourseEvent event) async* {
_courseRepository.updateCourse(event.updatedCourse);
}
Stream<CourseState> _mapDeleteCourseToState(DeleteCourseEvent event) async* {
_courseRepository.deleteCourse(event.course);
}
@override
void dispose() {
_courseSubscription?.cancel();
super.dispose();
}
}