Поток / Блок / Репозиторий / Firebase поток данных Flutter - PullRequest
1 голос
/ 23 февраля 2020

Я начинаю с flutter, так как хочу перенести мое приложение swift на Flutter, но я застрял, понимая шаблон Bloc / Repository / Firebase, поскольку я следую учебному пособию https://bloclibrary.dev/# / flutterfirestoretodostutorial Тесто Я использую базу данных в реальном времени, а не Firestore. Мое быстрое приложение - это, в основном, карта, куда вы можете добавлять оповещения с вашими фактическими координатами. Предупреждение отправляется в Firebase, а наблюдатель Firebase на карте обновляет карту, показывая только что добавленное предупреждение. Приведенный выше учебник должен помочь мне перенести мое приложение. Я просто не уверен, что понимаю логику c, стоящую за кодом. Мои проблемы: 2:

Сначала. Между объектом модели и объектом firebase существует слой Entity. Объясняется, что это будет способствовать наличию разных поставщиков данных, но я не вижу, чтобы это облегчало что-либо. В классе Model есть метод преобразования toEntity() и fromEntity(), а в классе Entity есть метод преобразования fromSnapshot() и toDocument(). Я не понимаю, какой смысл здесь. Это действительно необходимо? Что не так с выполнением преобразования непосредственно в классе Model, имеющем разные методы для каждого поставщика данных?

Второе. Внутри TodoBloc я не могу следовать логике c. Первое событие, которое отправляется в блок blo c в AppStart: LoadTodos.

BlocProvider<TodosBloc>(
          create: (context) {
            return TodosBloc(
              todosRepository: FirebaseTodosRepository(),
            )..add(LoadTodos());

В методе mapEventToState() из TodoBloc это событие отображается в этот поток:

Stream<TodosState> _mapLoadTodosToState() async* {
    _todosSubscription?.cancel();
    _todosSubscription = _todosRepository.todos().listen(
          (todos) => add(TodosUpdated(todos)),
        );
  }

Пока все хорошо. Как я понимаю, это подписывается на todos() Stream ()

@override
  Stream<List<Todo>> todos() {
    return todoCollection.snapshots().map((snapshot) {
      return snapshot.documents
          .map((doc) => Todo.fromEntity(TodoEntity.fromSnapshot(doc)))
          .toList();
    });
  }

, и это должно быть эквивалентом наблюдателя firebase в моем быстром приложении. Я не уверен, что понимаю эту часть внутри listen: (todos) => add(TodosUpdated(todos)).

Это отправляет себе (TodoBlo c) событие TodosUpdated, в которое блок blo c отобразит этот поток:

Stream<TodosState> _mapTodosUpdatedToState(TodosUpdated event) async* {
    yield TodosLoaded(event.todos);
  }

, это:

class TodosLoaded extends TodosState {
  final List<Todo> todos;

  const TodosLoaded([this.todos = const []]);

  @override
  List<Object> get props => [todos];

  @override
  String toString() => 'TodosLoaded { todos: $todos }';
}

Это фактический список объектов Firebase? Возвращает ли поток todos() весь узел каждый раз, когда в Firebase добавляется новый объект? В моем быстром приложении наблюдатель возвращает только .childAdded после первой загрузки узла. Должен ли я использовать пакет firebase_database с классом FirebaseList (https://pub.dev/documentation/firebase_database/latest/ui_firebase_list/FirebaseList-class.html), который будет просто возвращать список при любом изменении узла, как это делают мои наблюдатели в моем быстром приложении? Извините за этот очень длинный и запутанный вопрос, но я совершенно заблудился здесь, начиная с шаблона blo c. Большое спасибо за ваше время и помощь.

1 Ответ

1 голос
/ 24 февраля 2020

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

  1. todos() - это поток, поступающий из Firebase и возвращающий List<Todo>.
  2. _mapLoadTodosToState() - это метод blo c, который присоединяет прослушиватель blo c к todos(), а при обратном вызове .listen(onData) отправляет в blo c событие TodosUpdated(todos), содержащее последний список.
  3. TodosUpdated(todos) сопоставляется с _mapTodosUpdatedToState, что дает TodosLoaded(event.todos), новое состояние, которое BlocProvider использует для создания пользовательского интерфейса.

Спасибо, и я надеюсь, что это поможет другие изо всех сил пытаются освоить модель Blo C на более сложном уровне. Приветствия

...