【发布时间】:2021-10-03 23:03:21
【问题描述】:
我已经用颤振、getx 和 firebase 构建了一个 todo 应用程序。我有一个登录页面、注册页面和显示待办事项列表的待办事项页面。我正在使用 firebase_auth 包进行身份验证,使用 cloud_firestore 包来保存和检索 firestore 中的数据。我有 2 个模型 - 一个用于用户,另一个用于待办事项。
为了在 firestore 中保存待办事项,我有以下方法 -
Future<void> addTodo(String content, String uid) async {
try {
await firebaseFirestore
.collection("users")
.doc(uid)
.collection("todos")
.add({
"content": content,
"dateCreated": Timestamp.now(),
"done": false,
});
} catch (e) {
print(e.toString());
rethrow;
}
}
为了从 firestore 中检索 todos 列表,我使用下面的方法返回 todos 流
Stream<List<TodoModel>> todoStream(String uid) {
return firebaseFirestore
.collection("users")
.doc(uid)
.collection("todos")
.orderBy("dateCreated", descending: true)
.snapshots()
.map((event) {
List<TodoModel> retVal = List.empty(growable: true);
event.docs.forEach((element) {
TodoModel todo = TodoModel();
todo.todoId = element.id;
todo.content = element['content'];
todo.dateCreated = element['dateCreated'];
todo.done = element['done'];
print(todo.toString());
retVal.add(todo);
});
return retVal;
});
}
正如您所见,特定用户的 todo 与他们的 id 相关联。
现在在我的 todo 控制器的 onInit 方法中,我调用上面的函数来获取 todos 流
@override
void onInit() {
String uid = Get.find<AuthController>().user;
todoList.bindStream(DatabaseService().todoStream(uid));
super.onInit();
}
Auth 控制器返回用户的 id,然后将其馈送到 todoStream 函数以获取待办事项
在构建方法内的应用程序主页中,我正在像这样注入 Todo 控制器
Get.put(TodoController());
在 Scaffold 小部件的主体中,我使用 Obx 显示待办事项,就像这样
Obx(
() {
if (Get.find<TodoController>().todos.length > 0) {
return Expanded(
child: ListView.builder(
itemCount: Get.find<TodoController>().todos.length,
itemBuilder: (_, index) {
TodoModel todo = Get.find<TodoController>().todos[index];
return Card(
margin:
EdgeInsets.symmetric(horizontal: 20, vertical: 5),
child: Padding(
padding: EdgeInsets.all(10.0),
child: Row(
children: [
Expanded(
child: Text(
todo.content,
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.bold,
),
),
),
Checkbox(
value: todo.done,
onChanged: (newValue) {
print(newValue);
}),
],
),
),
);
},
),
);
} else {
return Text(
"Loading....",
style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold),
);
}
},
)
我面临的问题是当应用程序启动并且第一个用户登录时,我可以看到 todo 控制器已创建并初始化,并且他的 todos 列表显示在页面上。但是,当他注销并且另一个用户登录页面时,可以正确显示他的姓名,这意味着该用户被正确识别,但仍然显示第一个用户的待办事项列表。
这告诉我,当第二个用户登录时,todo 控制器的 onInit 方法没有被调用。
有人知道如何解决这个问题吗?
下面是我的 TodoController -
class TodoController extends GetxController {
Rxn<List<TodoModel>> todoList = Rxn<List<TodoModel>>();
List<TodoModel> get todos => todoList.value ?? [];
void clear() => todoList = Rxn<List<TodoModel>>();
@override
void onInit() {
String uid = Get.find<AuthController>().user;
print("onInit called=====================" + uid);
todoList.bindStream(DatabaseService().todoStream(uid));
print("todo bind stream done=========================");
super.onInit();
}
}
【问题讨论】:
标签: firebase flutter google-cloud-firestore flutter-getx