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
层。据解释,这将有助于拥有不同的数据提供者,但我真的不认为它有任何促进作用。在Model
class中有一个toEntity()
和一个fromEntity()
转换方法,在Entity
class中有一个fromSnapshot()
和 toDocument()
转换方法。我不明白这里有什么意义。真的有必要吗?直接在 Model
class 中进行转换有什么问题,每个数据提供者都有不同的方法?
第二。在 TodoBloc
里面我无法理解逻辑。
在 AppStart
发送到 bloc 的第一个事件是 LoadTodos
.
BlocProvider<TodosBloc>(
create: (context) {
return TodosBloc(
todosRepository: FirebaseTodosRepository(),
)..add(LoadTodos());
在 TodoBloc
的 mapEventToState()
方法中,该事件被映射到此流:
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 模式开始就迷路了。
非常感谢您的时间和帮助。
好的,我想我理解了它背后的逻辑,但是如果您发现我没有理解正确,请纠正我,因为在进入新范式的这个阶段非常重要,不要有任何误解。
todos()
是来自 Firebase 的流,returns 是 List<Todo>
。
_mapLoadTodosToState()
是将 bloc 侦听器附加到 todos()
的 bloc 方法,在 .listen(onData)
回调中,它向 bloc 发送包含最新的 TodosUpdated(todos)
事件列表。
TodosUpdated(todos)
被映射到 _mapTodosUpdatedToState
,这会产生
TodosLoaded(event.todos)
,BlocProvider 用于构建 UI. 的新状态
谢谢你,我希望这能帮助其他努力在更复杂的层面上掌握 BloC 模式的人。
干杯
我从 Flutter 开始,因为我想将我的 swift 应用程序移植到 Flutter,但是我在学习模式 Bloc/Repository/Firebase 时遇到困难 Bloc/Repository/Firebase 因为我正在学习教程 https://bloclibrary.dev/#/flutterfirestoretodostutorial dough 我使用实时数据库,而不是 Firestore。 我的 swift 应用程序基本上是一张地图,您可以在其中根据实际坐标添加警报。警报被发送到 Firebase,地图上的 Firebase 观察者更新地图,显示刚刚添加的警报。 上面的教程应该可以帮助我移植我的应用程序。我只是不确定我是否理解代码背后的逻辑。 我的顾虑是 2:
首先。在模型对象和 firebase 对象之间有一个 Entity
层。据解释,这将有助于拥有不同的数据提供者,但我真的不认为它有任何促进作用。在Model
class中有一个toEntity()
和一个fromEntity()
转换方法,在Entity
class中有一个fromSnapshot()
和 toDocument()
转换方法。我不明白这里有什么意义。真的有必要吗?直接在 Model
class 中进行转换有什么问题,每个数据提供者都有不同的方法?
第二。在 TodoBloc
里面我无法理解逻辑。
在 AppStart
发送到 bloc 的第一个事件是 LoadTodos
.
BlocProvider<TodosBloc>(
create: (context) {
return TodosBloc(
todosRepository: FirebaseTodosRepository(),
)..add(LoadTodos());
在 TodoBloc
的 mapEventToState()
方法中,该事件被映射到此流:
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 模式开始就迷路了。
非常感谢您的时间和帮助。
好的,我想我理解了它背后的逻辑,但是如果您发现我没有理解正确,请纠正我,因为在进入新范式的这个阶段非常重要,不要有任何误解。
todos()
是来自 Firebase 的流,returns 是List<Todo>
。_mapLoadTodosToState()
是将 bloc 侦听器附加到todos()
的 bloc 方法,在.listen(onData)
回调中,它向 bloc 发送包含最新的TodosUpdated(todos)
事件列表。TodosUpdated(todos)
被映射到_mapTodosUpdatedToState
,这会产生TodosLoaded(event.todos)
,BlocProvider 用于构建 UI. 的新状态
谢谢你,我希望这能帮助其他努力在更复杂的层面上掌握 BloC 模式的人。 干杯