Stream/Bloc/Repository/Firebase 数据流 Flutter

Stream/Bloc/Repository/Firebase data flow Flutter

我从 Flutter 开始,因为我想将我的 swift 应用程序移植到 Flutter,但是我在学习模式 Bloc/Repository/Firebase 时遇到困难 Bloc/Repository/Firebase 因为我正在学习教程 https://bloclibrary.dev/#/flutterfirestoretodostutorial dough 我使用实时数据库,而不是 Firestore。 我的 swift 应用程序基本上是一张地图,您可以在其中根据实际坐标添加警报。警报被发送到 Firebase,地图上的 Firebase 观察者更新地图,显示刚刚添加的警报。 上面的教程应该可以帮助我移植我的应用程序。我只是不确定我是否理解代码背后的逻辑。 我的顾虑是 2:

首先。在模型对象和 firebase 对象之间有一个 Entity 层。据解释,这将有助于拥有不同的数据提供者,但我真的不认为它有任何促进作用。在Modelclass中有一个toEntity()和一个fromEntity()转换方法,在Entityclass中有一个fromSnapshot()toDocument() 转换方法。我不明白这里有什么意义。真的有必要吗?直接在 Model class 中进行转换有什么问题,每个数据提供者都有不同的方法?

第二。在 TodoBloc 里面我无法理解逻辑。 在 AppStart 发送到 bloc 的第一个事件是 LoadTodos.

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

TodoBlocmapEventToState() 方法中,该事件被映射到此流:

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();
    });
  }

这应该相当于我的 swift 应用程序中的 firebase 观察器。 listen 闭包中的这一部分我不确定是否理解: (todos) => add(TodosUpdated(todos))

这会向自身 (TodoBloc) 发送一个 TodosUpdated 事件,该集团将在该事件上映射此流:

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 对象的实际列表吗?每次在 Firebase 中添加新对象时,todos() 是否会流 return 整个节点? 在我的 swift 应用程序中,观察者 return 仅在第一次下载节点后 .childAdded 。 我是否应该使用具有 FirebaseList class(https://pub.dev/documentation/firebase_database/latest/ui_firebase_list/FirebaseList-class.html) 的 firebase_database 包,它只会像我的观察者那样 return 节点上任何更改的列表在我的 swift 应用程序中? 很抱歉这个又长又乱的问题,但我在这里从 bloc 模式开始就迷路了。 非常感谢您的时间和帮助。

好的,我想我理解了它背后的逻辑,但是如果您发现我没有理解正确,请纠正我,因为在进入新范式的这个阶段非常重要,不要有任何误解。

  1. todos() 是来自 Firebase 的流,returns 是 List<Todo>
  2. _mapLoadTodosToState() 是将 bloc 侦听器附加到 todos() 的 bloc 方法,在 .listen(onData) 回调中,它向 bloc 发送包含最新的 TodosUpdated(todos) 事件列表。
  3. TodosUpdated(todos) 被映射到 _mapTodosUpdatedToState,这会产生 TodosLoaded(event.todos) ,BlocProvider 用于构建 UI.
  4. 的新状态

谢谢你,我希望这能帮助其他努力在更复杂的层面上掌握 BloC 模式的人。 干杯